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

后端 未结 3 433
深忆病人
深忆病人 2020-12-09 16:47

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?

         


        
3条回答
  •  自闭症患者
    2020-12-09 17:30

    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.

提交回复
热议问题