rwl / muntjac

A web application GUI toolkit
http://www.muntiacus.org
Apache License 2.0
42 stars 14 forks source link

Slowness #3

Closed novarc closed 12 years ago

novarc commented 12 years ago

Muntjac is really slow, even on a fast modern computer. For the Calc sample app, there's a significant delay for every UI event. Can this be sped up?

The API is quite nice; I'd love to use it, I hope it can be sped up.

Hacker News had a post on your project btw: http://news.ycombinator.com/item?id=3259296

I think you have a great project. As a Hacker-Newser commented on that thread above: "First make it possible, then make it fast, then make it beautiful." It's quite beautiful already, so all that needs to be done is 'fast' :)

EDIT: I didn't notice you were the OP on HN when I posted this. I guess you're well aware of the issue then.

rwl commented 12 years ago

This is indeed an issue that needs to be resolved. I have been trying to use AppStats on GAE to gather some performance data, but I've not made any headway yet.

My suspicion is that most of the time is spent unpickling and pickling the application state upon each request. If this is the case, defining some crafty __getstate__ and __setstate__ methods should speed things up greatly. Of course, there will be all sorts of other opportunities for to speed it up in places, but I think this is the main issue.

rwl commented 12 years ago

As I suspected:

         4293529 function calls (4246983 primitive calls) in 81.029 seconds

   Ordered by: internal time
   List reduced from 3476 to 20 due to restriction <20>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      124   54.371    0.438   54.374    0.439 {select.select}
       21    6.823    0.325   12.525    0.596 {cPickle.dump}
       21    6.646    0.316    7.952    0.379 {cPickle.load}
   174132    3.671    0.000    5.702    0.000 /usr/lib/python2.7/copy_reg.py:59(_reduce_ex)
  1374446    1.460    0.000    1.460    0.000 {hasattr}
   167212    0.444    0.000    0.775    0.000 /usr/lib/python2.7/copy_reg.py:46(_reconstructor)
    13577    0.368    0.000    0.926    0.000 muntjac/terminal/gwt/server/json_paint_target.py:264(escapeJSON)
   167563    0.332    0.000    0.332    0.000 {built-in method __new__ of type object at 0x84e840}
   144263    0.264    0.000    0.267    0.000 {getattr}
   199529    0.259    0.000    0.259    0.000 {method 'write' of 'cStringIO.StringO' objects}
   104663    0.253    0.000    0.385    0.000 muntjac/terminal/gwt/server/json_paint_target.py:240(_default)
   190805    0.227    0.000    0.243    0.000 {method 'get' of 'dict' objects}
    32013    0.216    0.000    0.216    0.000 {method 'copy' of 'dict' objects}
   126327    0.169    0.000    0.169    0.000 {isinstance}
12636/12360    0.162    0.000    0.982    0.000 muntjac/terminal/gwt/server/json_paint_target.py:313(addAttribute)
     5901    0.131    0.000    0.299    0.000 muntjac/terminal/gwt/server/json_paint_target.py:710(_attributesAsJsonObject)
25023/6849    0.116    0.000    0.193    0.000 muntjac/ui/abstract_component.py:343(isVisible)
15522/9937    0.111    0.000    0.241    0.000 muntjac/ui/abstract_component.py:701(fireRequestRepaintEvent)
    32734    0.110    0.000    0.275    0.000 /usr/lib/python2.7/re.py:228(_compile)
    30457    0.104    0.000    0.340    0.000 muntjac/ui/abstract_component.py:135(__setstate__)

Pickle dump and load show up using cProfile as being the main issue. escapeJSON() gets called very frequently and could do with optimization. I have used a dict in place of the switch statement, but if anyone has any ideas for improvement...

https://github.com/rwl/muntjac/blob/master/muntjac/terminal/gwt/server/json_paint_target.py#L238

novarc commented 12 years ago

Are you using cPickle? It can be a lot faster than regular pickle.

rwl commented 12 years ago

I have added a subclass of FileSession that uses the highest pickle protocol available. This gives a ~40%-50% reduction in the pickle dump and load call times using Python 2.7.

I have also added an InMemorySession for use with the demos. Please try version 1.0.4 to see the result.