Re: psyco

Jacob Smullyan <[email protected]>
Newsgroups gmane.comp.web.skunkweb
Message-ID <[email protected]>
On Wed, Jul 07, 2004 at 05:23:33PM +0200, Pierre-Fr?d?ric Caillaud wrote:
> 	And here are the timings :
> 
> globals :  0.571024894714
> locals :  0.261034011841
> psyco :  0.00352907180786
> 
> 	As you can see locals are a lot faster than globals... and yes, the 
> 	psyco  figure is real, but this really is an extreme case, using only 
> integers.  Usually Psyco accelerates between nothing and 2-3x

I'd have to call this a compelling benchmark!  Is this Python 2.3.4?

I am concerned about how this would affect includes.  One possibility
that occurs to me is to wrap components in a function if and only if
they have a compargs tag, which would directly yield the function
signature.  I'm not thrilled about the idea of the code being
generated for an STML file depending on whether it is called as an
include or a component; at least, by relying on <:compargs:>
declarations, the generated wrapper function would be somehow
explicit.

It should also be pointed out that it is fairly absurd to do any
heavy-lifting in STML at all, although I have seen it done.  That is
what Python components are for, and you can write functions in them to
your heart's content.  

That being said, if there is a way of using wrapper functions in STML
that has no undesirable side-effects and doesn't change current
behavior but improves performance, it would be a clear win.  (In
stoat, since I'm less encumbered by backwards compatibility issues,
I'd be more inclined to accept changes to current behavior for the
sake of an optimization than I would be in skunk proper.) There may be
other problems out there.  For instance, the

  from a import *

form is not legal outside of module scope:

  The from form with "*" may only occur in a module scope. If the wild
  card form of import -- "import *" -- is used in a function and the
  function contains or is a nested block with free variables, the
  compiler will raise a SyntaxError.  
  -- http://python.org/doc/2.3.4/ref/import.html

which would break the <:import:> tag -- perhaps not in a way that anyone
cares about, but nonetheless.

Does anyone see any other problems with this idea?  

> 
> 	***************************************
> 	* About <:val:> tag
> 	In the generated sources, I see :
> 
> __d.CURRENT_TAG = "<:val '`title`':>"
> __d.CURRENT_LINENO = '/webadmin/comps/products_list.comp:21'
> __t.val = title
> if __t.val is None:
>     __t.val = ""
> else:
>     __t.val = str(__t.val)
> __h.OUTPUT.write(__t.val)
> del __t.val
> 
> 	***************************************
> 	Comments :
> 	- I think it would be more appropriate to use a function for the  
> following code :
> 
> 	__t.val = title
> 	if __t.val is None:
> 	    __t.val = ""
> 	else:
> 	    __t.val = str(__t.val)
> 	__h.OUTPUT.write(__t.val)
> 	del __t.val
> 
> 	Even if inlining looks faster, I guess it's much slower here, due to 
> unoptimized globals, temp variable creation, and del. There is probably a  
> reason you did it that way, though. It could also be a method in the  
> OUTPUT object.

This could definitely be done and benchmarked against the current
code.    Patches will be considered :).
 
> 	And generally, I think it would be a good idea to use functions more 
> often in the compiled templates (for argument extraction, too). This would  
> make the code smaller (faster to compile, to load, takes less memory,  
> better locality of reference in cache, etc.)

Agreed.

> 	You could also save a few lookups by putting __h.OUTPUT.write in a  
> variable.

Well, that variable would have to be stashed somewhere, too.  The __h
mechanism is a bit expensive, admittedly.  In stoat, btw, there are no
games with stdout (can't be, as stoat is supposed to be threadsafe), and 
the output stream lives directly in the component namespace for components
that use it.  

> 	***************************************
> 	* About debug info and generated sources size
> 	In the generated sources, I see :
> 
> __d.CURRENT_TAG = '<:val "`(\'Non\',  
> \'Oui\')[prod.products_ready_to_ship]`":>'
> __d.CURRENT_LINENO = '/webadmin/comps/products_list.comp:136'
> 
> 	This is nice for debugging, however it causes code bloat.
> 	Same thing for including the sources in the compiled files.
> 	I think it would be better to create a file with only the compiled 
> 	python  bytecode (this is the file which is loaded all the time by 
> SkunkWeb), and  another file with the source and tag reference.
> 

This is somewhat configurable at the moment.  Look at the noTagDebug
and dontCacheSource options.

> 	Then, the compiled template would only contain lines like :
> __d.CURRENT_POSITION  = (1, 10, 20)
> 	the tuple being : file id, tag id, line id (or something like that).
> 	One tuple = one assignment (instead of two)
> 
> 	The tag, file, etc. would be retrieved from these ID's when an error 
> occurs.
 
Hmmm -- is tuple creation actually faster than assignment?

>>> def f():
...     x=3
...     y=2
... 
>>> def g():
...     x=(2, 3)
... 
...
>>> import time
>>> def timer(func, reps=1000):
...     t=time.time()
...     for i in xrange(reps):
...             func()
...     t1=time.time()
...     return (t1-t)/float(reps)
... 

>>> timer(f)
1.0530948638916015e-06
>>> timer(g)
1.222848892211914e-06
>>> timer(f, 10000)
9.9902153015136717e-07
>>> timer(g, 10000)
1.1955022811889649e-06

> 	That's all I can think about right now. I hope it helps !

It definitely does.  Thanks for the careful attention!  

Cheers,

js
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFA7Dl/uqamFyFXXLIRAplRAKDQydioDye5wrS1uAWtiYOY6NGU9gCfdndE
X+VDMKH+UKdRS9FCBuaQOLI=
=t6+1
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.