如何加快exec()的重复执行?

时间:2016-07-09 16:46:18

标签: python exec pypy

我有以下代码:

for k in pool:
    x = []
    y = []

    try:
        exec(pool[k])
    except Exception as e:
        ...
    do_something(x)
    do_something_else(y)

其中pool[k]是最终将项目附加到xy的python代码(这就是我使用exec代替eval的原因})。

我已经尝试使用pypy执行相同的代码但是对于这个特定的块我没有变得更好,exec的那一行仍然是我的瓶颈。

那就是说,我的问题是: 是否有更快的替代exec

如果没有,在这种情况下,你有什么办法可以加快速度吗?

- UPDATE -

澄清pool包含大约一百万个密钥,每个密钥与一个脚本相关联(大约50行代码)。脚本的输入在for loop之前定义,脚本生成的输出存储在xy中。因此,每个脚本在代码中都有一行说明x.append(something)y.append(something)。程序的其余部分将评估结果并对每个脚本进行评分。因此,我需要遍历每个脚本,执行它并处理结果。脚本最初存储在不同的文本文件中。 pool是通过解析这些文件获得的字典。

P.S。 使用预编译版本的代码:

for k in pool.keys():
    pool[k] = compile(pool[k], '<string>', 'exec')

我的速度提高了5倍,并不多,但已经有了。我正在尝试其他解决方案......

1 个答案:

答案 0 :(得分:2)

如果你真的需要以这种方式执行某些代码,请使用compile()来准备它。

即。不要将原始Python代码传递给exec而是传递给编译对象。在您的代码上使用compile()之前,使它们成为Python字节编译对象。

但是,编写一个能在输入参数上执行所需操作的函数(即pool [k]并返回与x和y对应的结果)会更有意义。

如果您从文件中获取代码,则还会导致IO速度降低  应付。因此,将这些文件编译为* .pyc。

会很高兴

您可以考虑在Python2中使用execfile()。

在池中使用函数的想法:

template = """\
def newfunc ():
%s
    return result
"""

pool = [] # For iterating it will be faster if it is a list (just a bit)
# This compiles code as a real function and adds a pointer to a pool
def AddFunc (code):
    code = "\n".join(["    "+x for x in code.splitlines()])
    exec template % code
    pool.append(newfunc)

# Usage:
AddFunc("""\
a = 8.34**0.5
b = 8
c = 13
result = []
for x in range(10):
    result.append(math.sin(a*b+c)/math.pi+x)"""

for k in pool:
    x = pool[k]()