There's a couple reasons why that particular benchmark won't get much faster.
- We only JIT compile functions that we've detected are hot. If we
didn't do this, compilation time would dwarf runtime.
- Second, we don't have any on-stack-replacement like the JVM, which
lets them detect hot loops and switch over to using the compiled code
without waiting for the next function call.
- We've also made the eval loop a bit slower in order to record
statistics so we can generate better code, so if you end up only using
the eval loop like you are in this case, you get a slowdown. :(
If you want to force u-s to compile a piece of code, I think the
preferred way is to throw it in a function and set __use_llvm__ on the
code object like so:
import timeit
setup = """
def f():
x = 0
while x < 100000000:
x += 1
try:
f.__code__.__use_llvm__ = True
except AttributeError:
pass
"""
print timeit.Timer(stmt="f()", setup=setup).timeit(number=1)
I get the following results:
[reid@muikyl ~]$ python t.py
7.62441802025
[reid@muikyl ~]$ unladen-swallow/python t.py
4.34114408493
Obviously, we could do a lot better, but we've tried to focus on real
world Python code instead of short numeric loops that aren't
idiomatic. For example, Collin's done a lot of work speeding up
function calls to builtin C functions and caching module level globals
that don't change.
Reid