Python 如何加速exec()的重复执行?
我有以下代码:Python 如何加速exec()的重复执行?,python,exec,pypy,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]是python代码,它最终会将项目附加到x和y(这就是为什么我使用exec而不是eval) 我已经尝试过用pypy执行相同的代码,但是对于这个特定的块,我没
for k in pool:
x = []
y = []
try:
exec(pool[k])
except Exception as e:
...
do_something(x)
do_something_else(y)
其中,pool[k]
是python代码,它最终会将项目附加到x
和y
(这就是为什么我使用exec
而不是eval
)
我已经尝试过用pypy执行相同的代码,但是对于这个特定的块,我没有得到太多的改进,使用exec
的那行代码仍然是我的瓶颈
尽管如此,我的问题是:
是否有比exec更快的替代方案
如果没有,在这种情况下,您是否有任何方法可以加快速度
--更新--
为了澄清,池
包含大约一百万个键,每个键都关联一个脚本(大约50行代码)。脚本的输入在循环之前定义,脚本生成的输出存储在x
和y
中。因此,每个脚本在代码中都有一行说明x.append(something)
和y.append(something)
。程序的其余部分将评估结果并为每个脚本打分。因此,我需要循环每个脚本,执行它并处理结果。脚本最初存储在不同的文本文件中<代码>池
是通过解析这些文件获得的字典
附言。
使用代码的预编译版本:
for k in pool.keys():
pool[k] = compile(pool[k], '<string>', 'exec')
池中k的键()
池[k]=编译(池[k],“”,'exec')
我的速度提高了5倍,虽然没有多大的提高,但已经有些进步了。我正在尝试其他解决方案…如果您确实需要以这种方式执行某些代码,请使用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 f in pool:
x = f()
我想你知道你在做什么,并且充分意识到潜在的。。。如果将代码传递给
exec
,尤其是多次执行同一代码,可以获得一定的加速。有关eval
、exec
和compile
的大量信息,请参阅。我知道安全风险,我只是在本地运行代码,只是一堆数学公式。我将检查编译。谢谢。如果exec()
确实是瓶颈,请避免使用它。制作pool
一个函数字典,每个函数都包含要执行的代码,然后用pool[k](x,y)
调用适当的函数。代码也包含if/else和其他内容,但更重要的是,我从文本文件中获取代码,因此首先将其作为字符串。您是否正在从池中执行每个项目,或者它们只是丢弃?x和y是列表,它们存储exec(代码)将生成的某些值,因此其中的部分代码是x.append(某物)。我将尝试exec(compile(code))
Woops,抱歉,看到了错误。编码有问题。我以为是()而不是[]。你为什么不在循环中使用x.append()-ing?@alec_djinn:在这里,我编辑了A来纠正错误。再次抱歉。是的,我知道x和y在每次迭代时都被初始化为[],这样做没关系。基本上,池包含许多不同的数学函数,这些函数应该产生一些结果,结果被附加到x和y,然后其他代码(…
)将评估结果有多好等等。。。在每次迭代中,都会对一组不同的函数进行求值。然后我建议将这些函数作为函数编写,并将指向这些函数的指针保存到池中。然后您可以执行pool[“one_func”]()等操作。如何提前生成这些函数并不重要。您仍然可以使用exec,但您的函数将是全局函数,并且只有指针通过循环。非常快。