Search code examples
pythoneval

Python: Way to speed up a repeatedly executed eval statement?


In my code, I'm using eval to evaluate a string expression given by the user. Is there a way to compile or otherwise speed up this statement?

import math
import random

result_count = 100000
expression = "math.sin(v['x']) * v['y']"

variable = dict()
variable['x'] = [random.random() for _ in xrange(result_count)]
variable['y'] = [random.random() for _ in xrange(result_count)]

# optimize anything below this line

result = [0] * result_count

print 'Evaluating %d instances of the given expression:' % result_count
print expression

v = dict()
for index in xrange(result_count):
    for name in variable.keys():
        v[name] = variable[name][index]
    result[index] = eval(expression) # <-- option ONE
    #result[index] = math.sin(v['x']) * v['y'] # <-- option TWO

For a quick comparison option ONE takes 2.019 seconds on my machine, while option TWO takes only 0.218 seconds. Surely Python has a way of doing this without hard-coding the expression.


Solution

  • You can also trick python:

    expression = "math.sin(v['x']) * v['y']"
    exp_as_func = eval('lambda: ' + expression)
    

    And then use it like so:

    exp_as_func()
    

    Speed test:

    In [17]: %timeit eval(expression)
    10000 loops, best of 3: 25.8 us per loop
    
    In [18]: %timeit exp_as_func()
    1000000 loops, best of 3: 541 ns per loop
    

    As a side note, if v is not a global, you can create the lambda like this:

    exp_as_func = eval('lambda v: ' + expression)
    

    and call it:

    exp_as_func(my_v)