On Jan 27, 2004, at 4:36 PM, Graham Fawcett wrote:
> Christoph Devenoges wrote:
>> hi,
>> why does
>> def nevowStyle(x, y):
>> return table(border=1, cellpadding=10, cellspacing=10)[
>> [tr[
>> [td['%s - %s' % (j, i)] for j in range(y)]] for i in
>> range(x)]]
>> take 3 times longer to execute then
>> def ptlStyle [html] (x, y):
>> '
'
>> for i in range(x):
>> ''
>> for j in range(y):
>> '%s - %s | ' % (i, j)
>> '
'
>> '
'
>> ?
>
> Good question. (Before going any further, we really ought to find a
> new name for this thing if we're going to keep talking about it. It's
> not really Nevow, after all, but a knock-off of Nevow. Perhaps 'ninn'
> (ninn is not Nevow)? Or 'Nuevo'? Or, if you don't like it, 'that damn
> Nevow-like thing that threatens to infect Quixote'.)
>
> One possible reason is that PTL is optimized for quick string-joining;
> the Nevow-thing is not.
>
> That's my only guess about performance. I never profiled the code, nor
> ever tried to optimize it. My advice would be to run the thing through
> the profiler, and see what you get (and maybe report back the
> results!).
The real reason is that creating new instances of objects is slow in
python. The real nevow will not create a new instance inside of
__getitem__; Graham's stan clone does. The real nevow will also
optimize stan trees down to a list of ["
Static
titleHello
Greetings, ", callable,
"!"]; the reason it does this is not because
concatenating strings is slow in python, but because creating instances
of objects and then iterating this tree of instances in order to render
them is.
Another reason is that isinstance can sometimes be slow. I had some
code in Woven which used Adapters from twisted.python.components
extensively. Since it only really adapted two or three types to a
specific interface, I figured I would optimize and get a nice speed
boost by switching to isinstance in these critical parts of the code
which were used repeatedly. It turns out that indexing a dictionary
with a class object (which is all that t.p.components really does, when
it comes down to it) is often faster than having a tree of if
isinstance: elif isinstance: elif isinstance: checks. The real nevow
uses components to switch on the type of objects in the stan tree. In
fact, there is already an outstanding patch which optimizes this
generic component lookup strategy down to an index into a {string:
callable} dictionary, bypassing twisted.python.components entirely. It
has been reported that this patch speeds the real nevow up by a factor
of 2; the only reason I haven't applied it yet is that I have been
busy.
Woven used a W3C compliant DOM implementation to represent on-disk HTML
templates in memory for manipulation. It was (? alot) times slower than
nevow is. Switching to the lighter weight stan-dom implementation sped
things up considerably (I think about an order of magnitude, but I
didn't do any really scientific tests). So I haven't even spent much
time on optimizing it, although there are certain places which I have
already flagged as optimizable but have not optimized because I wanted
to keep the code simple. So nevow hasn't even begun to near the
optimization stage, because we haven't needed it so far.
When it comes down to it, nevow is not really about speed -- it is
about giving you the ability to write very complex web applications,
spending as much time in pure Python code as you like, while still
allowing the expression of the abstraction between the on-disk HTML
template and the Python code.
dp