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
