为什么 list(range) 比 [i for i in range()] 快?

t0 = time.time()
list(range(100000))
print(time.time()-t0)
>>> 0.00400090217590332
t0 = time.time()
[i for i in range(100000)]
print(time.time()-t0)
>>> 0.009000301361083984

理解 list() 和列表表达式之间的性能差异的关键在于反汇编:

import dis
N = 10000
def m1():
return list(range(N))
def m2():
return [i for i in range(N)]
dis.dis(m1)
dis.dis(m2)

m1输出的反汇编:

  8           0 LOAD_GLOBAL              0 (list)
3 LOAD_GLOBAL 1 (range)
6 LOAD_GLOBAL 2 (N)
9 CALL_FUNCTION 1
12 CALL_FUNCTION 1
15 RETURN_VALUE

如反汇编所示,整个转换只是一个字节码指令,该指令是对该list方法的函数调用,而且整个实现list均在C中进行。

另一方面,m2的反汇编:

 11           0 BUILD_LIST               0
3 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (N)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 12 (to 28)
16 STORE_FAST 0 (i)
19 LOAD_FAST 0 (i)
22 LIST_APPEND 2
25 JUMP_ABSOLUTE 13
>> 28 RETURN_VALUE

如反汇编所示,列表表达式比list(range(N))复杂得多,列表表达式的循环发生在多个字节码指令上。编译器循环的解析指令,增加了运行时间。

原内容参见:

https://stackoverflow.com/questions/52649252/why-in-python-does-the-listrange-way-much-faster-than-the-i-for-i-in-range

为什么 list(range) 比 [i for i in range()] 快?的更多相关文章

  1. 1.xrange和range不要混了,2.range(len(xx))不如用enumerate

    range()是列表, xrange()是迭代 >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i i ...

  2. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  3. [LeetCode] Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  4. [LeetCode] Bitwise AND of Numbers Range 数字范围位相与

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  5. Notes: DOM Range

    通过DOM范围可以选择文档中的某个区域,而不需考虑节点的界限,例如文本高亮的处理就可以使用范围来实现. 1.Range的创建 使用document的createRange来创建一个范围,该方法返回一个 ...

  6. swift中Range的使用书名

    在swift中Range有两种用法 1.把字符串转换成NSString来使用 //这里是把swift的字符换转换成了nsstring 使用 let str :NSString = text.strin ...

  7. input range样式更改,模拟滑块

    input range 样式更改,js模拟滑块实时更新数据. 效果图: html 代码: <div> <span class="slider"></s ...

  8. 合并分区(merge range)对事务日志的影响

    分区维护作业执行失败,错误信息如下:数据库 'XXX' 的事务日志已满.若要查明无法重用日志中的空间的原因,请参阅 sys.databases 中的 log_reuse_wait_desc 列. [S ...

  9. VB默认属性、动态数组、Range对象的默认属性的一点不成熟的想法

    1.默认属性 VB6.0有默认属性的特性.当没有给对象指定具体的属性时,"默认属性"是VB6.0将使用的属性.在某些情形下,省略常用属性名,使代码更为精简. 因为CommandBu ...

随机推荐

  1. java 遍历数组常见的3种方式

    1.for循环,最常见 2.利用foreach 3.利用jdk自带的方法  --> java.util.Arrays.toString()

  2. 关于SqlServer表结构 2(回归基础)

    关于SqlServer表结构的问题.先来了解一下SqlServer中的数据类型以及它们的用法 整型: 短整型 smallint 整型 int 长整型 bitint 标识列:identity(它是只读的 ...

  3. 一文入门人工智能的明珠:生成对抗网络(GAN)

    一.简介 在人工智能领域内,GAN是目前最为潮流的技术之一,GAN能够让人工智能具备和人类一样的想象能力.只需要给定计算机一定的数据,它就可以自动联想出相似的数据.我们学习和使用GAN的原因如下: 1 ...

  4. Hello GCN

    参考链接: https://www.zhihu.com/question/54504471/answer/611222866 1 拉普拉斯矩阵 参考链接: http://bbs.cvmart.net/ ...

  5. 10、Strategy 策略模式 整体地替换算法 行为型模式

    1.模式说明 策略模式比较好理解,就是将程序中用到的算法整体的拿出来,并有多个不同版本的算法实现,在程序运行阶段,动态的决定使用哪个算法来解决问题. 2.举例 排序算法的问题,假如我们的程序中需要对数 ...

  6. GitLab 配置模板

    GitLab 配置模板 GitLab 使用模板和参数生成配置文件. 一般来说,我们会通过 gitlab.rb 文件修改配置,例如 Nginx 相关配置. gitlab.rb 只能使用特定的几个 Ngi ...

  7. 常哥带你认识NoSQL和Redis的强大

    各位朋友,这篇文章是针对Redis快速了解的内容,为了学好Redis在这里首先跟大家聊聊NoSQL相关内容,有了概念和方向后,我们再学习Redis大家会感觉得心应手. [公众号dotNet工控上位机: ...

  8. Go 中的动态作用域变量

    这是一个 API 设计的思想实验,它从典型的 Go 单元测试惯用形式开始: func TestOpenFile(t *testing.T) { f, err := os.Open("notf ...

  9. CSS动画实例:图文切换

    先准备好一张图片,在页面中放置一个类名为container的层作为图文容器,在该层中再定义两个层:一个类名为image-box的层放置图片,一个类名为text-desc的层放置文本描述,HTML代码描 ...

  10. 最新版CentOS8系统安装和基本配置

    一.Centos8新版简介 Redhat公司在2019年5月推出了rhel8,年底推出了centos8,紧接着也会把相关的技术认证完全转换为新平台. 阿里云.华为云目前也已推出centos8的公共镜像 ...