[Checkins] SVN: z3c.pt/trunk/ Engine now uses cStringIO.
Malthe Borch
mborch at gmail.com
Fri Feb 22 17:37:52 EST 2008
Log message for revision 84148:
Engine now uses cStringIO.
Changed:
U z3c.pt/trunk/docs/HISTORY.txt
U z3c.pt/trunk/setup.py
U z3c.pt/trunk/z3c/pt/BENCHMARKS.txt
U z3c.pt/trunk/z3c/pt/clauses.py
U z3c.pt/trunk/z3c/pt/expressions.py
U z3c.pt/trunk/z3c/pt/io.py
U z3c.pt/trunk/z3c/pt/translation.py
U z3c.pt/trunk/z3c/pt/translation.txt
U z3c.pt/trunk/z3c/pt/utils.py
-=-
Modified: z3c.pt/trunk/docs/HISTORY.txt
===================================================================
--- z3c.pt/trunk/docs/HISTORY.txt 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/docs/HISTORY.txt 2008-02-22 22:37:52 UTC (rev 84148)
@@ -1,11 +1,12 @@
Changelog
---------
-Version 0.4 - in development
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Version 0.4 - February 22, 2008
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- Engine now uses cStringIO yielding a 2.5x performance
+ improvement. Unicode is now handled correctly.
-
Version 0.3 - December 23, 2007
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: z3c.pt/trunk/setup.py
===================================================================
--- z3c.pt/trunk/setup.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/setup.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = '0.3.3'
+version = '0.4'
setup(name='z3c.pt',
version=version,
Modified: z3c.pt/trunk/z3c/pt/BENCHMARKS.txt
===================================================================
--- z3c.pt/trunk/z3c/pt/BENCHMARKS.txt 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/BENCHMARKS.txt 2008-02-22 22:37:52 UTC (rev 84148)
@@ -1,13 +1,27 @@
Benchmarks
==========
- zope.pagetemplate z3c.pt
-Hello World 3.55 1
-1000 x 10 table 6.02 1
+These benchmarks should not be taken too seriously but they do give an
+idea of how this package measures up to Zope's default TAL
+engine. Also included is a comparison to a pure python implementation.
-Source
-------
+Results
+-------
+ zope.pagetemplate z3c.pt pure python
+Hello World 3.6 1 0.02
+1000 x 10 table 14.0 1 0.63
+
+There's a setup cost in using a template language which explains the
+50x factor in the 'Hello World' benchmark versus a pure python
+implementation.
+
+Certainly a specialized implementation will always be faster. But
+there's still some room for improvement.
+
+Benchmark source code
+---------------------
+
>>> from z3c.pt import PageTemplate
>>> from zope.pagetemplate.pagetemplate import PageTemplate as z3PageTemplate
@@ -18,7 +32,7 @@
... Hello World!
... </div>""")
- >>> # for i in range(300000): a = template()
+ >>> # for i in range(90000): a = template()
>>> template = z3PageTemplate()
>>> template.pt_edit("""\
@@ -26,8 +40,16 @@
... Hello World!
... </div>""", 'text/xhtml')
- >>> # for i in range(300000): a = template()
+ >>> # for i in range(90000): a = template()
+ >>> def hello_world():
+ ... return u"""\
+ ... <div>
+ ... Hello World!
+ ... </div>"""
+
+ >>> for i in range(9000000): a = hello_world()
+
1000 x 10 table:
>>> table = [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) \
@@ -68,9 +90,10 @@
... for row in table:
... out.write('<tr>')
... for c in row.values():
- ... out.write('<td>%s</td>' % c)
+ ... d = c+1
+ ... out.write('<td><span class="column-%d">%s</span></td>' % (d, d))
... out.write('</tr>')
... return out.getvalue()
- >>> # for i in range(20): a = bigtable(table=table)
+ >>> # for i in range(40): a = bigtable(table=table)
Modified: z3c.pt/trunk/z3c/pt/clauses.py
===================================================================
--- z3c.pt/trunk/z3c/pt/clauses.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/clauses.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -1,5 +1,7 @@
from expressions import value
+from utils import unicode_required_flag
+
class Assign(object):
"""
>>> from z3c.pt.io import CodeIO; stream = CodeIO()
@@ -464,11 +466,24 @@
temp = stream.save()
if self.count == 1:
- stream.write("_out.write(%s)" % self.expressions[0])
+ expr = self.expressions[0]
else:
self.assign.begin(stream, temp)
- stream.write("_out.write(%s)" % temp)
-
+ expr = temp
+
+ if unicode_required_flag:
+ stream.write("_urf = %s" % expr)
+ stream.write("try:")
+ stream.indent()
+ stream.write("_out.write(str(_urf))")
+ stream.outdent()
+ stream.write("except TypeError:")
+ stream.indent()
+ stream.write("_out.write(unicode(_urf, 'utf-8'))")
+ stream.outdent()
+ else:
+ stream.write("_out.write(str(%s))" % expr)
+
def end(self, stream):
if self.count != 1:
self.assign.end(stream)
Modified: z3c.pt/trunk/z3c/pt/expressions.py
===================================================================
--- z3c.pt/trunk/z3c/pt/expressions.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/expressions.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -50,13 +50,13 @@
try:
# we use the ``parser`` module to determine if
# an expression is a valid python expression
- parser.expr(expr)
+ parser.expr(expr.encode('utf-8'))
except SyntaxError, e:
if j < len(string):
continue
raise e
-
+
expressions.append(expr)
i = j + 1
Modified: z3c.pt/trunk/z3c/pt/io.py
===================================================================
--- z3c.pt/trunk/z3c/pt/io.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/io.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -25,7 +25,6 @@
self.scope = [set()]
self._variables = {}
-
self.t_counter = 0
def save(self):
@@ -58,7 +57,8 @@
def write(self, string):
self.cook()
- StringIO.write(self, self.indentation_string * self.indentation + string + '\n')
+ StringIO.write(
+ self, self.indentation_string * self.indentation + string + '\n')
def getvalue(self):
self.cook()
Modified: z3c.pt/trunk/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/z3c/pt/translation.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/translation.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -18,7 +18,7 @@
\t_target_language = target_language
%s
-\treturn _out.getvalue()
+\treturn _out.getvalue().decode('utf-8')
"""
def attribute(ns, factory):
Modified: z3c.pt/trunk/z3c/pt/translation.txt
===================================================================
--- z3c.pt/trunk/z3c/pt/translation.txt 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/translation.txt 2008-02-22 22:37:52 UTC (rev 84148)
@@ -35,8 +35,9 @@
... <p tal:omit-tag="True">No paragraph here either.</p>
... <p tal:omit-tag="False">A paragraph here.</p>
... <span tal:replace="'Hello World!'">Hello Universe!</span>
+ ... <span tal:content="'%s'" />
... </div>
- ... """
+ ... """ % (u'La Pe\xf1a').encode('utf-8')
>>> print render(body)
<div>
@@ -60,7 +61,7 @@
</ul>
Hello World!
<div>Hello World!</div>
- <BLANKLINE>
+ 0
1
2
3
@@ -69,6 +70,7 @@
No paragraph here either.
<p>A paragraph here.</p>
Hello World!
+ <span>La Peña</span>
</div>
Error handling
Modified: z3c.pt/trunk/z3c/pt/utils.py
===================================================================
--- z3c.pt/trunk/z3c/pt/utils.py 2008-02-22 22:36:51 UTC (rev 84147)
+++ z3c.pt/trunk/z3c/pt/utils.py 2008-02-22 22:37:52 UTC (rev 84148)
@@ -1,8 +1,19 @@
import zope.i18n
+from cStringIO import StringIO
+
+import sys
import cgi
-from StringIO import StringIO
+import logging
+# check if we're able to coerce unicode to str
+try:
+ str(u'La Pe\xf1a')
+ unicode_required_flag = False
+except UnicodeEncodeError:
+ unicode_required_flag = True
+ logging.warn("Default system encoding is set to '%s'; the template engine will perform better if an encoding that coerces gracefully to unicode is used ('utf-8' recommended).")
+
def handler(key=None):
def decorate(f):
def g(node):
More information about the Checkins
mailing list