Am 05.05.2010, 00:59 Uhr, schrieb Martin Liebscher  
<[email protected]>:

>> create 1000 new nodes this creates a bunch of objects each with
>> subobjects
>> and attributes which all detect changes and send a "needs updating"
>> event.
>> Just sending all those events is what takes up such a long time.
>
> I attached a call graph generated from profiler output that covers these
> tree lines of code posted before. May be you can just take a look on it
> if it supports your assumptions... [not sure if attachments allowed
> here]

Thanks for the call graph. I suppose this output was generated by  
cProfile? In my own tests I used cProfile and the textual output. Your  
call graph and my results back then seem to match.

I assume the upper number in the blocks means "percentage of total time  
spent in this function including calls to other functions" and the lower  
number means "percentage of total time spent only in this function,  
excluding 'child' functions". You can see a lot of the blocks which have  
either a high call count or a high percentage of time spent in them are  
related to "observable", "events" and "pubsub". The central block here is  
recursiveAttributeObservable.__setattr__ . It's called 10,000 times.  
getattr is called 12,000 times. There are also lots of other blocks which  
have a call count of 3,000 to 4,000. It's hard to pick a single block in  
which a lot of time is spent, the time is wasted around the observable and  
event sending. I suspect doing all those function calls is really slow  
(especially in python. Also more than 50,000 function calls to add 76  
nodes (26 rects + 50 lines) is way too much.

In conclusion, the graph seems to support my theory. Excessive amount of  
function calls in observing changes and sending notifications. There are  
also a few other places that could need optimization later, but this is  
the main problem.

>> There are opportunities to enhance this scheme, ideas:
>>
>> - objects should maybe send events directly to the canvas instead of
>> sending events to their parent objects which then relay to the
>> canvas.
>> Might cause problems with render to surface nodes.
>> - once the canvas is dirty, no dirty events are sent at all. This
>> should
>> reduce the cost of sending events by a huge factor.
>
> Mhh, not really familiar with fc2 and its internals... not sure...
> The idea from Chris looks straight forward for me and should definitely
> solve this (specific) problem...
>>
>> 1) implement a "freeze" "thaw" scheme, so the user could turn off the
>> system when they now they are updating a lot.
>>
> I assumed that something like this already exists (similar to
> enablespeedmode)...

I think something like this can be added easily, but it might break parts  
which rely on the system. E.g. the render-to-surface nodes that I pointed  
out. You could start by removing __setattr__ in some way. This will stop  
all the change monitoring and thus notification sending. Not sure what the  
result will look like, but you can try :)

> I have to solve an other problem with fc2 first (the Tree.py demo with
> its connector lines from fc1). If this usecase can also be solved with
> fc2... it would make sense to put some effort in this.

I used to have some code for this, but I can't find it anymore. It was  
quite simple. I think I just bound the "transformChanged" event of the two  
rectangles which are connected by the line. When one of their transforms  
changed, I updated the end points of the line.

-Matthias
_______________________________________________
FloatCanvas mailing list
[email protected]
http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to