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?
I think you are optimising the wrong end. If you want to perform the same operation for a lot of numbers you should consider using numpy:
import numpy
import time
import math
import random
result_count = 100000
expression = "sin(x) * y"
namespace = dict(
x=numpy.array(
[random.random() for _ in xrange(result_count)]),
y=numpy.array(
[random.random() for _ in xrange(result_count)]),
sin=numpy.sin,
)
print ('Evaluating %d instances '
'of the given expression:') % result_count
print expression
start = time.time()
result = eval(expression, namespace)
numpy_time = time.time() - start
print "With numpy:", numpy_time
assert len(result) == result_count
assert all(math.sin(a) * b == c for a, b, c in
zip(namespace["x"], namespace["y"], result))
To give you an idea about the possible gain I've added a variant using generic python and the lambda trick:
from math import sin
from itertools import izip
start = time.time()
f = eval("lambda: " + expression)
result = [f() for x, y in izip(namespace["x"], namespace["y"])]
generic_time = time.time() - start
print "Generic python:", generic_time
print "Ratio:", (generic_time / numpy_time)
Here are the results on my aging machine:
$ python speedup_eval.py
Evaluating 100000 instances of the given expression:
sin(x) * y
With numpy: 0.006098985672
Generic python: 0.270224094391
Ratio: 44.3063992807
The speed-up is not as high as I expected, but still significant.