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

How to speed up a repeated execution of exec()?

我有以下代码:

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

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

其中 pool[k] 是 python 代码,最终会将项目附加到 xy (这就是为什么我使用 exec 而不是 eval).

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

也就是说,我的问题是: exec 是否有更快的替代方案?

如果没有,在这种情况下您是否有任何解决方法来加快速度?

--更新--

澄清一下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 倍,虽然不多,但已经很不错了。我正在尝试其他解决方案...

如果您确实需要以这种方式执行某些代码,请使用 compile() 进行准备。

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

但是,编写一个函数来执行您需要的输入参数(即对应于 x 和 y 的 pool[k] 和 return 结果会更有意义。

如果您从文件中获取代码,您也会遇到 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 f in pool:
    x = f()