这个问题已经在这里有了答案 :
Python 3枚举比Python 2慢是有原因的吗? (2个答案)
5年前关闭。
我一直在试图理解为什么在某些情况下Python 3与Python 2相比实际上要花费很多时间,以下是我从python 3.4到python
2.7进行验证的几种情况。
注意:我已经经历了一些问题,例如,为什么Python3中没有xrange函数?
与
python2相比,在python3中循环并比python2慢得多,
并且在Python3中使用相同的代码也比Python2慢,但是我感到我没有得到这个问题背后的实际原因。
我已经尝试了这段代码来展示它是如何发挥作用的:
MAX_NUM = 3*10**7
# This is to make compatible with py3.4.
try:
xrange
except:
xrange = range
def foo():
i = MAX_NUM
while i> 0:
i -= 1
def foo_for():
for i in xrange(MAX_NUM):
pass
当我尝试使用py3.4和py2.7运行该程序时,得到的结果如下。
注意:这些统计信息来自64 bit
带有2.6Ghz
处理器的计算机,并使用time.time()
单循环计算时间。
Output : Python 3.4
-----------------
2.6392083168029785
0.9724123477935791
Output: Python 2.7
------------------
1.5131521225
0.475143909454
我真的不认为已将2.7while
或xrange
3.4应用于更改,或从2.7更改为3.4,我知道range
它已经开始xrange
在py3.4中起作用,但正如文档所述
range()
现在的行为就像以前一样xrange()
,只是它可以使用任意大小的值。后者不再存在。
这意味着从xrange
to更改range
非常等同于名称更改,但是可以使用任意值。
我也验证了反汇编的字节码。
下面是该函数的反汇编字节码foo()
:
Python 3.4:
---------------
13 0 LOAD_GLOBAL 0 (MAX_NUM)
3 STORE_FAST 0 (i)
14 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (i)
12 LOAD_CONST 1 (0)
15 COMPARE_OP 4 (>)
18 POP_JUMP_IF_FALSE 34
15 21 LOAD_FAST 0 (i)
24 LOAD_CONST 2 (1)
27 INPLACE_SUBTRACT
28 STORE_FAST 0 (i)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
python 2.7
-------------
13 0 LOAD_GLOBAL 0 (MAX_NUM)
3 STORE_FAST 0 (i)
14 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (i)
12 LOAD_CONST 1 (0)
15 COMPARE_OP 4 (>)
18 POP_JUMP_IF_FALSE 34
15 21 LOAD_FAST 0 (i)
24 LOAD_CONST 2 (1)
27 INPLACE_SUBTRACT
28 STORE_FAST 0 (i)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
下面是该函数的反汇编字节码foo_for()
:
Python: 3.4
19 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (xrange)
6 LOAD_GLOBAL 1 (MAX_NUM)
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
20 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
Python: 2.7
-------------
19 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (xrange)
6 LOAD_GLOBAL 1 (MAX_NUM)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
20 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
如果我们比较两个字节码,它们将产生相同的反汇编字节码。
现在,我想知道从2.7到3.4的什么变化实际上导致给定代码段中执行时间的巨大变化。
不同之处在于int
类型的实现。蟒3.X使用任意大小的整数类型(long
在2.X)排他地,而在Python
x为值高达sys.maxint
更简单的int
类型被用于使用一个简单的Clong
引擎盖下。
将循环限制为 long
整数后,Python 3.x会更快:
>>> from timeit import timeit
>>> MAX_NUM = 3*10**3
>>> def bar():
... i = MAX_NUM + sys.maxsize
... while i > sys.maxsize:
... i -= 1
...
Python 2:
>>> timeit(bar, number=10000)
5.704327821731567
Python 3:
>>> timeit(bar, number=10000)
3.7299320790334605
我用sys.maxsize
作为sys.maxint
从Python 3的下降,但整数值基本相同。
因此,Python 2中的速度差异仅限于第一个(2 63)-64位为1整数,(2 31)-32位系统为1整数。
由于您无法在Python 2上使用该long
类型xrange()
,因此我没有对该函数进行比较。
问题内容: 我有一个简单的任务:计算每个字母在一个字符串中出现的次数。我已经使用了它,但是在一个论坛上我看到了使用/比每个字母都要慢得多的信息。我认为它只能在字符串中进行一次遍历,而解决方案则必须遍历该字符串四次(在这种情况下)。为什么这么慢? 问题答案: 允许您计算任何可哈希对象,而不仅仅是子字符串。两种解决方案都是-time。您的测量结果表明,迭代和散列单个字符的开销大于运行4倍。 可以 使用
下面的代码将简单的值持有者映射到一个对象,它在Java中的运行速度比使用XCode 7 beta3“最快、积极的优化[-ofast]”的Objective-C快15倍以上。在Java中,我可以获得超过280m/sec的查找,但在objc示例中只有大约19m。(我在这里发布了相应的Java代码,因为这是作为一个Swift比较开始的:Swift Dictionary即使经过优化也很慢:是否不断保留/发
许多用户认为这是切换到 Pytorch 的原因,但我还没有找到牺牲最重要的实际质量、速度来换取急切执行的理由/解释。 下面是代码基准测试性能,TF1与TF2-TF1的运行速度从47%到276%不等。 我的问题是:在图形或硬件级别,是什么导致了如此显着的减速? 寻找详细的答案-我已经熟悉广泛的概念。相关Git 规格:CUDA 10.0.130、cuDNN 7.4.2、Python 3.7.4、Win
我昨天对一个答案发表了评论,其中有人在正则表达式中使用了,而不是或。我说使用范围或数字说明符可能比使用字符集更快。 我决定今天测试一下,并惊讶地发现(至少在C#regex引擎中)似乎比其他两个似乎没有太大区别的任何一个都慢。这是我的测试输出超过10000个随机字符串,其中包含1000个随机字符,其中5077个实际上包含一个数字: 这对我来说是一个惊喜,有两个原因,如果有人能解释一下,我会很感兴趣:
我发现 比 Python 2 和 3 中的函数慢。 Python 2 蟒蛇 3 为什么<code>max</code>(<code>O(n)</code>)比<code>sort</code>函数(<code<O(nlogn)</code>)慢?