Python 和 Go 在循环时候的性能对比

2019-07-16 23:07:22 +08:00
 Buffer2Disk

如题

两个 for 循环分别 6000 次,来嵌套; 中间休息 5 秒钟;

python 代码如下(版本 2.7 )

golang 的代码如下(版本 1.12)

python 在循环的时候,cpu 消耗 70%

golang 在循环的时候,cpu 消耗 0.6%、

这 2 个仅仅是简单的循环,性能差别就有这么大么,还是我姿势哪里不对?

7267 次点击
所在节点    程序员
54 条回复
ysc3839
2019-07-16 23:29:16 +08:00
你是如何测量 “ cpu 消耗” 的呢?
Buffer2Disk
2019-07-16 23:39:47 +08:00
@ysc3839 看 top 啊
shakespaces
2019-07-16 23:43:53 +08:00
其实 python 里面是两个 5999 次😂,虽然和性能没关系
moodasmood
2019-07-16 23:45:30 +08:00
我虽然说不出哪里不对,到直觉告诉我,这他妈明显有问题啊。至于哪里有问题,请楼下解答
niubee1
2019-07-17 00:00:56 +08:00
for num in xrange(1, 100):
[(lambda _:time.sleep(5))([j for j in xrange(1, 6000)]) for i in xrange(1, 6000)]

试试嘛
niubee1
2019-07-17 00:04:41 +08:00
事实上你用 xrange 替换 range 就能让 CPU 开销降到 20%, 用列表解析, 就是我这个就只有 0 附近了。开不开心, 意不意外?
neoblackcap
2019-07-17 00:10:08 +08:00
range 返回列表,耗时在这
Buffer2Disk
2019-07-17 00:13:10 +08:00
@niubee1 我要循环的其实是 2 个 list,只不过抽象成了上面的 range,

list 有办法优化么。。。。
Buffer2Disk
2019-07-17 00:15:07 +08:00
@neoblackcap 对,但是我要循环的,其实就是列表
Buffer2Disk
2019-07-17 00:19:16 +08:00
@neoblackcap 你的意思是,range 返回列表的时候,是消耗 cpu 的主要部分嘛?

我怎么感觉是循环的时候消耗的,我另外一份代码循环的时候,是直接 2 个 list 来嵌套循环的,没有 range

然后加了 sleep(0.1) ,cpu 就降价来了,但是这样的话,循环的耗时就大大增加了
niubee1
2019-07-17 00:21:09 +08:00
你是要判断一个列表里的内容是不是存在与另外一个列表嘛, 设有列表 l1, l2
for i in [idx for idx, flag in enumerate([ i in l2 for i in l1]) if flag]:
print "列表 l1 中 %s 位的元素在列表 l2 中存在......"
Buffer2Disk
2019-07-17 00:24:58 +08:00
@niubee1 我看你这个是用 in 和 not in 来判断元素是否在 list 存在是嘛?

这个我试过了,cpu 消耗依然很高,估计 in 和 not in 的内部实现也是通过这种循环来实现的
fy
2019-07-17 00:26:20 +08:00
看到 2.7,吓得我赶紧看看日历,怀疑自己穿越了
niubee1
2019-07-17 00:27:25 +08:00
你也可以使用 itertools.product

要高效循环, 肯定要用到 itertools, 你基础库都不搞明白就出来浪, 这样子不好
neoblackcap
2019-07-17 00:31:32 +08:00
@Buffer2Disk 你每次调用 range 都要申请内存,创建一个列表啊,能快才奇怪。你用 top 来计算 CPU 耗时的方法本身就不对。
而且你只是判断一个元素是否在另外一个列表里面,你转成集合,用求交集的方法啊。那个才 O(n),你现在这个粗糙的实现方式可是 O(n^2)。
你觉得是循环在耗时,那么请你在 Python 里面创建好两个列表,然后再开始你的循环计时,而且停 5s 有什么用啊?你写日志不好么?
raysonx
2019-07-17 00:32:07 +08:00
Go 是编译型语言。内部的两层循环没有动作默认会被编译器优化掉
guog
2019-07-17 00:36:17 +08:00
这都不是一个层次的对比,如果仅仅对比循环,你完全可以用 while 啊,不创建任何 list,CPU 也是零。
aheadlead
2019-07-17 00:39:27 +08:00
上次看到这么比较语言性能的,还是在易语言的官网
niubee1
2019-07-17 00:40:14 +08:00
之前的例子不是很恰当, 重新写了个
两个长度 6000 的列表对比元素
Buffer2Disk
2019-07-17 00:55:00 +08:00
@niubee1 好的,谢谢大佬,我研究研究

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/583594

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX