Am 07.07.2010, 23:30 Uhr, schrieb shi <[email protected]>: > >> > Just sending all those events is what takes up such a long time. > > Hello list, > > FC2 is really great and easy to use for my purpose, > but the speed issue when adding objects to the canvas > is a showstopper. To keep a long story short I > added 60000 objects to the canvas, went to the shop, got back home, > and then killed the process. > > I'm curious to know if someone is actively looking at this issue?
I'd really like to make fc2 work even with big workloads. Most of the functionality required for this is already present. As I've stated in the past, I don't have any time to spend on this right now and the foreseeable future. Mainly because the summer of code '08 is long over by now and I don't have the time/money for fc2 at this time. > I took a first look by stepping through the code in the debugger, > but the meta class magic that happens when adding an object currently > is not entirely clear to me, nor is it clear what could be the impact of > somehow preventing all this magic from happening. The biggest mistake I made for fc2 is this: I wanted to spare the user the calls to "Refresh" in all kinds of places. This requires fc2 to internally track all changes done to an object. This allows things like detecting if the changes are really in the view or not. If you are changing things outside of the view, the Refresh would not be called. Detecting all attribute changes has two very big drawbacks: 1) It is extremely slow, because you have to override things like __setattr__. Calling __setattr__ hundreds of thousands of times is extremely slow in my benchmarks. 2) All attributes of classes like the looks, the models, the views, canvas, ... have to be able to send "I changed" events. I had the choice to make this either automatic or have a lot of redundant, error prone code. I chose the automatic way. In hindsight, I'd just rip observables completely out and make the user call Refresh() where needed. Saves tens/hundred thousands of calls for detecting/sending/processing "change" events. The second "meta" (although not meta classes) problem is this: The user can supply arbitrary data models to the canvas. E.g. you can get "House" objects directly out of your database and visualize them with a rectangle. There's not need to manually create Rectangles from the "House" objects. This way if somebody changes the coordinates of the House in your database you can see the change on the canvas without having to remove/re-add the rectangle belonging to the house. Additionally fc2 allows you to write custom renderer back-ends. The gcrenderer is just an example implementation of a back-end. Making the rendering back-end independent required yet another layer. So observables, arbitrary models and independent renderer back-ends complicated the implementation of the simple "draw objects on canvas" idea. If I had had more time, I'd refactored and made this easier for other people to work on. In my tests this part was not really slow, I haven't tested with 60,000 objects though. I did some small experiments when I added the r-tree c library support and cProfile mainly spent time executing the same functions many many times, most of them related to observables. So I think 60,000 objects are handleable with refinements to the implementation (and provided most of the objects are not visible as looping over 60,000 objects in python and rendering each individually will be non-interactive anyway). > Would it make sense to try to extend the pubsub Publisher() so that it > can > be instructed to temporarily suspend dispatching certain messages to its > listeners? As a way to implement a "freeze" of some kind? I think changing Publisher is not enough, you'd have to rip out observables completely. Ripping out observables has another side-effect: Render-to-surface nodes use the "changed" events model to determine if they need to redraw themselves. This also needs to be signaled by the user. I'm not sure if observables also played a role in caching transform chains, but I don't think they did iirc. Conclusion: - If you have time to spend, rip out observables and then do a quick benchmark. This might take longer than you anticipate initially. - If you want to make your project work right now, you might want to abandon FC2 and try a quick test with FC1 instead. Or use a completely different framework (like a 2d game engine which does all the looping in C). -Matthias P.S.: If you look into floatcanvas2.config there's a functon called "enableSpeedmode". This is a bit like ripping out observables, but it's just a quick hack and the benchmark still shows too many redundant function calls. _______________________________________________ FloatCanvas mailing list [email protected] http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
