Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何加速exec()的重复执行?_Python_Exec_Pypy - Fatal编程技术网

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,但您的函数将是全局函数,并且只有指针通过循环。非常快。