Slowness in compile()/eval()

Pedro Rodriguez pedro_rodriguez at club-internet.fr
Thu Jan 17 08:19:11 EST 2002


Hello,

while investigating on lazy evaluations, I found these strange
results while doing some timings. I expected that using :
    d = eval(code)
where
    code = compile("i+i", '<string>', 'eval')

should give an execution time of the same magnitude as :
    d = f(i)
where
    def f(i): return i+i

it turns out to be almost 4x slower. 

Investigating with the dis module, I noticed that the result of
compile uses LOAD_NAME where a function uses LOAD_FAST. Is this
due to local namespace lookup ?

It turns out that using something like (with some tweaks) :
    code = compile("def f(i):\n return i*i\n", '<string>', 'exec')
    eval(code)
gives the expected computation time.

I think I must be missing something on evaluation, but what ?
TIA

-- 

Pedro

Benchmark code :

----------------------------------------------------------------
fun.py
----------------------------------------------------------------

import time
import dis
import sys

NNN = 1
NNN = 1000000


def inline():
    for i in range(NNN):
        d = i+i

def func():
    def f(i): return i+i
    for i in range(NNN):
        d = f(i)

def eval_str():
    for i in range(NNN):
        d = eval("i+i")

def eval_code():
    code = compile("i+i", "<string>", "eval")
    for i in range(NNN):
        d = eval(code)

def eval_fast():
    code = compile("def new_f(i):\n return i+i\n", "<string>", "exec")
    eval(code)
    f = locals()["new_f"] # XXX language lawyers required on this
    for i in range(NNN):
        d = f(i)

def do(f):
    t0 = time.time()
    f()
    tf = time.time()
    print "%-10s : %6.3f" % (f.func_name, tf - t0)

do(inline)
do(func)
do(eval_str)
do(eval_code)
do(eval_fast)

----------------------------------------------------------------
RESULTS on RedHat 7.2 / PIII 800Mhz
----------------------------------------------------------------

$ python1.5 fun.py
inline     :  1.414
func       :  2.627
eval_str   : 79.604
eval_code  :  9.127
eval_fast  :  2.655

$ python2.1 fun.py
inline     :  1.249
func       :  2.367
eval_str   : 113.443   Ouch !!!
eval_code  :  7.641
eval_fast  :  2.366

$ python2.2 fun.py
inline     :  1.171
func       :  2.724
eval_str   : 110.448   Ouch !!!
eval_code  :  7.811
eval_fast  :  2.715



More information about the Python-list mailing list