我有以下代码:
for k in pool:
x = []
y = []
try:
exec(pool[k])
except Exception as e:
...
do_something(x)
do_something_else(y)
其中pool[k]
是最终将项目附加到x
和y
的python代码(这就是我使用exec
代替eval
的原因})。
我已经尝试使用pypy执行相同的代码但是对于这个特定的块我没有变得更好,exec
的那一行仍然是我的瓶颈。
那就是说,我的问题是:
是否有更快的替代exec
?
如果没有,在这种情况下,你有什么办法可以加快速度吗?
- UPDATE -
澄清,pool
包含大约一百万个密钥,每个密钥与一个脚本相关联(大约50行代码)。脚本的输入在for loop
之前定义,脚本生成的输出存储在x
和y
中。因此,每个脚本在代码中都有一行说明x.append(something)
和y.append(something)
。程序的其余部分将评估结果并对每个脚本进行评分。因此,我需要遍历每个脚本,执行它并处理结果。脚本最初存储在不同的文本文件中。 pool
是通过解析这些文件获得的字典。
P.S。 使用预编译版本的代码:
for k in pool.keys():
pool[k] = compile(pool[k], '<string>', 'exec')
我的速度提高了5倍,并不多,但已经有了。我正在尝试其他解决方案......
答案 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]()