Horrible scene_update_post performance
The scene_update handlers are called on every update, which is basically the Blender's refresh rate. On empty scene I measured 200 updates/sec. On every cycle Blender has to update the whole scene and run the python code on top of that - that leaves a very small processing time for the python part (cca 17ms is ok which translates into 60 updates/sec).

Thus any code that is being run inside scene_update handlers is extremely performance sensitive and should be optimized.

Optimization tips:


Before updating or processing anything, check if it has to be updated or processed. In this case run the code only when number of objects changes, check the length of the scene.objects list first:

import bpy

num_objects = 0

def handler(scene):
    global num_objects
    if len(scene.objects) == num_objects:
        # Nothing to do
        return
    num_objects = len(scene.objects) 
    # Your code here
    return

bpy.app.handlers.scene_update_post.append(handler)


You can use global variables, custom properties, properties of objects or binary flags to memorize when code needs to be run.
Update or process your stuff in an efficient way:


pre-sort arrays where it will increase performance
use data-structures optimized for the task (like dictionaries, numpy arrays, etc.) and access them in an efficient way
use list comprehension for cycling through list elements
use local variables wherever possible
profile your code to know where the bottlenecks are: How can you profile a Python script?

If it needs to be really fast, write it in Fortran, C, C++ or Assembly, then call it from Python.


Python is not C, Java or Haskell. Knowledge of how other languages perform to Python isn't very well transferable, your python code will pick up speed and performance with your experience in the language. The next example illustrates it well (from: wiki.python.org - Performance Tips):


  % timeit.py -s 'x = 47' 'x * 2' 
  loops, best of 3: 0.574 usec per loop 
  % timeit.py -s 'x = 47' 'x &lt;&lt; 1' 
  loops, best of 3: 0.524 usec per loop 
  % timeit.py -s 'x = 47' 'x + x' 
  loops, best of 3: 0.382 usec per loop
  
  Note that there is a significant advantage in Python to adding a number to itself instead of multiplying it by two or shifting it left by one bit. In C on all modern computer architectures, each of the three arithmetic operations are translated into a single machine instruction which executes in one cycle, so it doesn't really matter which one you choose.


Other resource for performance tips: Optimizing Python Code