Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
为什么pypy中的代码比默认的python解释器慢?_Python_Performance_Pypy - Fatal编程技术网

为什么pypy中的代码比默认的python解释器慢?

为什么pypy中的代码比默认的python解释器慢?,python,performance,pypy,Python,Performance,Pypy,给定多个玩家n,我需要找到H,所有元组的列表,其中每个元组是联盟的组合(玩家的组合,例如,(1,2,3)是玩家1,2和3的组合。((1,2,3),(4,5),(6),)是联盟的组合,也是元组)这尊重了这条规则:每个玩家只出现一次(也就是说,只出现在一个联盟中)。 另外,在代码中,每种联盟组合称为布局 开始时,我编写了一个代码段,其中我计算了所有联盟的所有组合,并为每个组合检查了规则。问题是,对于5-6名玩家来说,联盟组合的数量已经太大了,以至于我的电脑坏了。 为了避免大部分计算(所有可能的组合、

给定多个玩家
n
,我需要找到
H
,所有元组的列表,其中每个元组是联盟的组合(玩家的组合,例如,(1,2,3)是玩家1,2和3的组合。((1,2,3),(4,5),(6),)是联盟的组合,也是元组)这尊重了这条规则:每个玩家只出现一次(也就是说,只出现在一个联盟中)。 另外,在代码中,每种联盟组合称为布局

开始时,我编写了一个代码段,其中我计算了所有联盟的所有组合,并为每个组合检查了规则。问题是,对于5-6名玩家来说,联盟组合的数量已经太大了,以至于我的电脑坏了。 为了避免大部分计算(所有可能的组合、循环和ifs),我编写了以下内容(我进行了测试,与前面的代码片段相当):

说明:假设n=3

首先,我创建所有可能的联盟:

coalitions = [[(1,),(2,),(3,)],[(1,2),(1,3),(2,3)],[(1,2,3)]]
然后我用明显的组合初始化H:每个玩家在他自己的联盟中,每个玩家在最大的联盟中

H = [((1,),(2,),(3,)),((1,2,3),)]
然后我计算所有可能的布局形式:

combs = [(1,2)]   #(1,2) represents a layout in which there is 
                  #one 1-player coalition and one 2-player coalition.
我计算排列(排列)。 最后,对于每个烫发和每个梳子,我计算出不同的可能布局。I
设置
结果(
布局
),以删除重复项并添加到H

H = [((1,),(2,),(3,)),((1,2,3),),((1,2),(3,)),((1,3),(2,)),((2,3),(1,))]
比较如下:

python script.py

  • 4:0.00052094455337秒
  • 5:0.0038321018219秒
  • 6:0.0408189296722秒
  • 7:0.431486845016秒
  • 8:6.05224680901秒
  • 9:76.4520540237秒
pypy脚本.py

  • 4:0.00342392921448秒
  • 5:0.066803932899秒
  • 6:0.311077833176秒
  • 7:1.13124799728秒
  • 8:11.5973010063秒
  • 9:Got phut

为什么pypy那么慢?我应该更改什么?

这里有一个关于
itertools.product
的Pypy问题

请注意,我们的目标是确保itertools不会比 简单的Python,但我们并不真正关心如何使它完全一样快(或更快) 更快)作为普通Python。只要速度不太慢,就可以了。(在 至少我不同意你关于a)还是b)更容易阅读的观点:-)


在不详细研究代码的情况下,它似乎大量使用了
itertools
组合、排列和乘积函数。在常规的CPython中,这些都是用编译过的C代码编写的,目的是使它们变得更快。Pypy没有实现C代码,因此这些函数的速度较慢也就不足为奇了。

这里是关于
itertools.product
的Pypy问题

请注意,我们的目标是确保itertools不会比 简单的Python,但我们并不真正关心如何使它完全一样快(或更快) 更快)作为普通Python。只要速度不太慢,就可以了。(在 至少我不同意你关于a)还是b)更容易阅读的观点:-)


在不详细研究代码的情况下,它似乎大量使用了
itertools
组合、排列和乘积函数。在常规的CPython中,这些都是用编译过的C代码编写的,目的是使它们变得更快。Pypy没有实现C代码,因此这些函数的速度较慢也就不足为奇了。

首先,我想指出的是,您正在研究,在生成所有子集之后,这可能会简化下一部分的工作。例如,很容易知道每个钟组有多大;OEIS已经有了

我手工编写循环以生成钟集;这是我的密码:

cache={0:(),1:((set([1]),),)}
def bell(x):
#更改这些行以更改备忘录。
如果x在缓存中:
返回缓存[x]
上一个=钟形(x-1)
新=[]
对于以前版本中的集合:
r=[]
对于范围内的标记(透镜(组)):
l=[s |集合([x]),如果i==在枚举(集合)中为i,s标记else s]
r、 附加(元组(l))
新.扩展(r)
new.append(set+(set([x]),)
缓存[x]=元组(新)
还新
为了实用,我在这里写了一些备忘录。但是,通过注释一些代码并编写一些其他代码,您可以获得以下未注释的版本,我将其用于基准测试:

def铃(x):
如果x==0:
返回()
如果x==1:
返回((集合([1]),),)
上一个=钟形(x-1)
新=[]
对于以前版本中的集合:
r=[]
对于范围内的标记(透镜(组)):
l=[s |集合([x]),如果i==在枚举(集合)中为i,s标记else s]
r、 附加(元组(l))
新.扩展(r)
new.append(set+(set([x]),)
缓存[x]=元组(新)
还新
我的数字是基于一个有几年历史的Thinkpad,我大部分的工作都是在它上面完成的。大多数较小的案例都太快了,无法可靠地进行测量(前几次试验中,每次试验都没有一毫秒),因此我的基准测试是通过
bell(9)
测试
bell(11)

CPython 2.7.11的基准测试,使用标准
timeit
模块:

$ python -mtimeit -s 'from derp import bell' 'bell(9)'
10 loops, best of 3: 31.5 msec per loop
$ python -mtimeit -s 'from derp import bell' 'bell(10)'
10 loops, best of 3: 176 msec per loop
$ python -mtimeit -s 'from derp import bell' 'bell(11)'
10 loops, best of 3: 1.07 sec per loop
在PyPy 4.0.1上,也使用
timeit

$ pypy -mtimeit -s 'from derp import bell' 'bell(9)'
100 loops, best of 3: 14.3 msec per loop
$ pypy -mtimeit -s 'from derp import bell' 'bell(10)'
10 loops, best of 3: 90.8 msec per loop
$ pypy -mtimeit -s 'from derp import bell' 'bell(11)'
10 loops, best of 3: 675 msec per loop
因此,我得出的结论是,
itertools
在其预期习惯用法之外使用时速度不是很快。钟形数字在组合上很有趣,但它们不是从我能找到的任何简单的
itertools
小部件组合中自然产生的

为了响应您最初的查询,即如何使其更快:只需打开代码即可。希望这有帮助


~C.

首先,我想指出的是,您正在研究,在生成完所有t之后,这可能会简化下一部分的工作
$ pypy -mtimeit -s 'from derp import bell' 'bell(9)'
100 loops, best of 3: 14.3 msec per loop
$ pypy -mtimeit -s 'from derp import bell' 'bell(10)'
10 loops, best of 3: 90.8 msec per loop
$ pypy -mtimeit -s 'from derp import bell' 'bell(11)'
10 loops, best of 3: 675 msec per loop