[Zope-CVS] CVS: Packages/cZPT - README.txt:1.1

Shane Hathaway shane@cvs.zope.org
Mon, 16 Sep 2002 11:44:34 -0400

Update of /cvs-repository/Packages/cZPT
In directory cvs.zope.org:/tmp/cvs-serv23309

Added Files:
Log Message:
Optimized TALInterpreter and restrictedTraverse() in C.

This code is just educational for now.  Before doing much more, we should
write performance tests and try out Pyrex.

=== Added File Packages/cZPT/README.txt ===

Shane Hathaway

This code (TAL/cTALInterpreter.c and OFS/cTraversable.c) is an
experiment in Python to C optimization.  What I wanted to learn:

- how to convert Python code to C while handling memory management and
exceptions correctly.  It's very hard to match the safety of the Python

- whether there is a benefit in optimizing TALInterpreter and

- whether there are unforeseen problems.

- whether there is a better, more maintainable way to do this.

What I learned:

- To write maintainable and safe C code from Python, you have to
follow some conventions.  These are the conventions I discovered to be
the most beneficial:

  - Every variable of type "PyObject*" must be either owned or
  borrowed at all times.  A variable should not be owned in one part
  of the function and borrowed in other parts.  Violating this rule
  often leads to memory management problems.  A reasonable exception
  is that a function argument may be turned into an owned reference
  early in the function.

  - Functions with any complexity should use "goto" to handle
  exceptions.  Combined with the two macros CHECKPTR and CHECKINT,
  this makes exception handling much simpler.

  - Python variables usually need to be owned references.  When
  converting a Python function, start by declaring an owned
  "PyObject*" for every local Python variable (except for variables
  that will be represented as basic C types).

Even after I followed all these rules, I still made mistakes that led
to segfaults.  I fixed all the bugs I found, but it's still
unsatisfying to know that there may be other memory management bugs

- There is indeed a benefit to optimizing this code.  In fact, even
though cTALInterpreter is not fully optimized (it doesn't use the most
efficient Python calls everywhere), the Python profiler seems to show
a significant speedup.  It would be beneficial for someone to write a
real performance test.  There is a simple speed test in OFS/ for
cTraversable.restrictedTraverse() that shows a 2x-3x speed improvement
over the standard restrictedTraverse().

- An unforeseen issue is that error tracebacks involving
TALInterpreter don't show as much information.

A better way?

Pyrex might be a better option for doing this.  I haven't tried it,
but it allows you to write code that's almost Python while integrating
C variables into the source.  I understand it generates the C code,
which you can then compile into an extension.  The resulting extension
has a good chance of being just as safe as the original Python code
and about as fast as an extension written by hand.

Psyco is another option, but it seems likely to me that Psyco would
not generate code that is as fully optimized as what Pyrex generates.
Psyco should be better at general optimization, however.  There is no
reason one should not be able to combine both techniques into the same

So this code, cTALInterpreter and cTraversable, should be considered
merely educational until someone comes on board who can write the
speed tests and try out Pyrex.