为什么在循环范围()在Python比使用while循环更快?
有一天我正在做一些Python基准testing,并且遇到了一些有趣的事情。 下面是两个或多或less做同样的事情循环。 循环1需要循环2的两倍左右才能执行。
循环1:
int i = 0 while i < 100000000: i += 1
循环2:
for n in range(0,100000000): pass
为什么第一个循环这么慢? 我知道这是一个微不足道的例子,但这引起了我的兴趣。 range()函数有什么特别之处,它比以同样的方式递增variables更有效率?
看到反汇编python字节码,你可能会得到更具体的想法
使用while循环:
1 0 LOAD_CONST 0 (0) 3 STORE_NAME 0 (i) 2 6 SETUP_LOOP 28 (to 37) >> 9 LOAD_NAME 0 (i) # <- 12 LOAD_CONST 1 (100000000) # <- 15 COMPARE_OP 0 (<) # <- 18 JUMP_IF_FALSE 14 (to 35) # <- 21 POP_TOP # <- 3 22 LOAD_NAME 0 (i) # <- 25 LOAD_CONST 2 (1) # <- 28 INPLACE_ADD # <- 29 STORE_NAME 0 (i) # <- 32 JUMP_ABSOLUTE 9 # <- >> 35 POP_TOP 36 POP_BLOCK
循环体有10个操作
使用范围:
1 0 SETUP_LOOP 23 (to 26) 3 LOAD_NAME 0 (range) 6 LOAD_CONST 0 (0) 9 LOAD_CONST 1 (100000000) 12 CALL_FUNCTION 2 15 GET_ITER >> 16 FOR_ITER 6 (to 25) # <- 19 STORE_NAME 1 (n) # <- 2 22 JUMP_ABSOLUTE 16 # <- >> 25 POP_BLOCK >> 26 LOAD_CONST 2 (None) 29 RETURN_VALUE
循环体有3个操作
运行C代码的时间比intepretor短得多,可以忽略。
range()
在C中实现,而i += 1
被解释。
使用xrange()
可以使大数更快。 从Python 3.0开始, range()
与以前的xrange()
相同。
必须说的是,while循环中有很多对象的创build和破坏。
i += 1
是相同的:
i = i + 1
但是由于Python ints是不可变的,它不会修改现有的对象; 而是创造一个全新的具有新价值的对象。 这基本上是:
i = new int(i + 1) # Using C++ or Java-ish syntax
垃圾收集器也将有大量的清理工作。 “对象创造是昂贵的”。
因为在解释器中用C编写的代码更经常运行。 即i + = 1是在Python中,所以慢(比较),而范围(0,…)是一个C调用,for循环将主要在C中执行。
Python内build的大部分方法调用都是以C代码的forms运行的。 必须解释的代码要慢得多。 在内存效率和执行速度方面,差异是巨大的。 python内部已经被优化到极致,最好利用这些优化。
- JetBrains Resharper 9最终testing运行器错误:NUnit.Core.UnsupportedFrameworkException:跳过加载程序集{MyAssembly}
- 使用Moqvalidation方法调用
- Android Studio Gradle项目“无法启动虚拟机守护进程/初始化”
- 在SQL Server中强制查询超时
- Junit:分解集成testing和unit testing
- Haskelltesting工作stream程
- 禁用Python nosetests
- testingwebforms应用程序的最佳方式是什么(ASP.NET)
- Python基本和子类的unit testing