在回答另一个question时,我建议使用timeit来测试用正整数和负整数索引列表的区别。下面是代码:
import timeit
t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=10000000)
print (t)
t=timeit.timeit('mylist[-1]',setup='mylist=list(range(100))',number=10000000)
print (t)我使用python2.6运行了这段代码:
$ python2.6 test.py
0.587687015533
0.586369991302然后我用python 3.2运行了它:
$ python3.2 test.py
0.9212150573730469
1.0225799083709717然后我抓了抓头,在google上搜索了一下,然后决定在这里发布这些观察结果。
操作系统: OS-X (10.5.8) -- Intel Core2Duo
对我来说,这似乎是一个相当大的差异( 1.5倍以上的差异)。有没有人知道为什么python3要慢得多--尤其是对于这样一个普通的操作?
编辑
我在我的Ubuntu桌面(Intel i7)上运行了相同的代码,并取得了与python2.6和python3.2类似的结果。这似乎是一个操作系统(或处理器)依赖的问题(其他用户在Linux机器上也看到了相同的行为--参见注释)。
编辑2
在其中一个答案中请求了启动横幅,如下所示:
Python 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin以及:
Python 3.2 (r32:88452, Feb 20 2011, 10:19:59)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin更新
我刚刚从http://www.python.org/download/安装了python2.7.3和python3.2.3的新版本
在这两种情况下,我都把
Pythonx.x.3 Mac 32位i 386/PPC安装程序(用于MacOSX10.3至10.6 2)
因为我在OSX10.5上。以下是新的时间表(通过多次试验,这些时间是合理一致的):
python 2.7
$python2.7 test.py
0.577006101608
0.590042829514python 3.2.3
$python3.2 test.py
0.8882801532745361
1.034242868423462发布于 2012-07-09 18:24:18
这似乎是Python3.2的一些构建的工件。在这一点上最好的假设是,所有32位英特尔的生产都有放缓,但没有64位的。请继续阅读以了解更多细节。
你没有运行足够的测试来确定任何东西。重复测试很多次,相同测试的值从0.31到0.54不等,这是一个巨大的变化。
因此,我使用10x (数字)和repeat=10 (使用一系列不同的Python2和Python3安装)运行了您的测试。丢弃顶部和底部的结果,平均其余8个,除以10 (以获得与测试相等的数字),下面是我看到的:
1. 0.52/0.53 Lion 2.6
2. 0.49/0.50 Lion 2.7
3. 0.48/0.48 MacPorts 2.7
4. 0.39/0.49 MacPorts 3.2
5. 0.39/0.48 HomeBrew 3.2因此,看起来3.2实际上在[99]中稍微快一些,与[-1]的速度大致相同。
然而,在10.5台机器上,我得到了以下结果:
1. 0.98/1.02 MacPorts 2.6
2. 1.47/1.59 MacPorts 3.2回到原来的(Lion)机器上,我以32位模式运行,得到如下结果:
1. 0.50/0.48 Homebrew 2.7
2. 0.75/0.82 Homebrew 3.2所以,看起来32位才是最重要的,而不是Leopard对Lion,gcc 4.0对gcc 4.2或clang,硬件差异等等。这将有助于在Leopard下测试64位的构建,使用不同的编译器等等,但不幸的是,我的Leopard盒是第一代英特尔Mini (32位核心独奏CPU),所以我不能做那个测试。
作为进一步的间接证据,我在Lion盒上做了一系列其他快速测试,看起来32位3.2比2.x慢了50%,而64位3.2可能比2.x稍快一些。但是,如果我们真的想支持这一点,就需要有人挑选并运行一个真正的基准套件。
无论如何,我对此最好的猜测是,当优化3.x分支时,没有人会在32位i386 Mac构建上付出很大的努力。这对他们来说是个合理的选择。
或者,他们甚至没有在32位i386期间付出太多的努力.这种可能性可能解释了为什么OP在linux盒上看到了2.x和3.2的相似结果,而Otto Allmendinger认为3.2在linux盒上的速度类似于2.6。但是由于他们都没有提到他们是运行32位还是64位linux,所以很难知道这是否相关。
还有许多其他不同的可能性,我们还没有排除,但这似乎是最好的。
发布于 2012-07-09 20:14:38
下面是说明至少部分答案的代码:
$ python
Python 2.7.3 (default, Apr 20 2012, 22:44:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
2.55517697334
>>> t=timeit.timeit('mylist[99L]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
3.89904499054
$ python3
Python 3.2.3 (default, May 3 2012, 15:54:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> t=timeit.timeit('mylist[99]',setup='mylist=list(range(100))',number=50000000)
>>> print (t)
3.9906489849090576python3没有旧的int类型。
发布于 2012-07-09 22:24:11
Python3 range()是Python2 xrange()。如果要在Python3代码中模拟Python2 range(),则必须使用list(range(num)。num越大,原始代码的差异就越大。
索引应该独立于列表中存储的内容,因为列表只存储对目标对象的引用。这些引用都是非类型化的,而且都是同一类型的。因此,列表类型在技术上是一个同构的数据结构。索引意味着将索引值转换为开始地址+偏移量。计算偏移量是非常有效的,最多减法一次。与其他操作相比,这是非常便宜的额外操作。
https://stackoverflow.com/questions/11400472
复制相似问题