Hi Makoto,

currently sys._getframe() is mostly killing the jit
since it currently needs access to all frame objects,

if i remember correct (arigo, fijal or anto will know for sure),
the jit currently just bails out if it gets a sys._getframe call

(which easyly explain the ~34 times slower  in your test)

i think there are ways to support it,
but i currently don't have the time/knowledge to check which of them work

-- Ronny

On 05/27/2012 06:24 AM, Makoto Kuwata wrote:
Hi,

I found that sys._getframe() (or sys._getframe().f_locals) is
very slow in PyPy 1.8.
For example, the following takes only 0.0398 sec on PyPy 1.8:

       def f5(x): return f4(x)
       def f4(x): return f3(x)
       def f2(x): return f1(x)
       def f1(x): reutrn None               ## just return None
       for _ in xrange(1000000):
           f5(0)

But the next one takes 1.3563 sec.

       def f5(x): return f4(x)
       def f4(x): return f3(x)
       def f2(x): return f1(x)
       def f1(x): reutrn sys._getframe(1)    ## calls sys._getframe(1)
       for _ in xrange(1000000):
           f5(0)

Is there any plan to make it faster in the future release?


Background
----------

I'm an author of Tenjin, a high-speed template engine for Python.
Tenjin supports PyPy officially, and I received a report that
there are some cases in which Tenjin is very slow on PyPy.

I investigated report and found that it is the sys._getframe()
and sys._getframe().f_locals that makes Tenjin much slow on PyPy.

Tenjin uses sys._getframe(1).f_locals in order to access to
caller's local variables. It is necessary for Tenjin.


Benchmark
---------

Here is a benchmark script to measure cost of sys._getframe(1)
and sys._getframe(1).f_locals.
(You must install Benchmarker library to run it.)

https://gist.github.com/2802160

Benchmark result shows that:

* Cost of sys._getframe(1) and sys._getframe(1).f_locals is
   not so much on CPython but very big on PyPy.
* Nested depth os function call affects to cost of them.
   For example:

       def f5(x): return f4(x)
       def f4(x): return f3(x)
       def f2(x): return f1(x)
       def f1(x): reutrn sys._getframe(1)
       f5(0)

   is much slower than:

       def f2(x): return f1(x)
       def f1(x): reutrn sys._getframe(1)
       f2(0)



By the way, PyPy is awesome.
It is not only faster than CPython but also has high-level
compatibility with CPython. Almost of all test script of Tenjin
works on PyPy. Great.
I hope Tenjin works much faster on PyPy.

--
regards,
makoto kuwata
_______________________________________________
pypy-dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-dev

_______________________________________________
pypy-dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to