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 个仅仅是简单的循环,性能差别就有这么大么,还是我姿势哪里不对?

7292 次点击
所在节点    程序员
54 条回复
crella
2019-07-17 12:40:04 +08:00
都是读取一行,按 tab 取列,修改文字,io 写入一行
Buffer2Disk
2019-07-17 13:07:24 +08:00
@neoblackcap 确实,算差集的时间复杂度要小很多
shuax
2019-07-17 13:28:37 +08:00
用 sleep 测试效率,学到了。
SeaRecluse
2019-07-17 14:12:50 +08:00
python3.6 未复现
占用大概 8%
encro
2019-07-17 14:23:20 +08:00
python 每次 for 循环都重新 range 生成列表,而 golang 没有,这明显不是同样的对比啊。
encro
2019-07-17 14:24:42 +08:00
这种比 cpu 没有意义,使用 time 命令比总执行时间还好点。
mengzhuo
2019-07-17 14:25:51 +08:00
空的 For 循环会被 Go 的 SSA 干掉的
Buffer2Disk
2019-07-17 15:13:00 +08:00
@neoblackcap 不过有个疑问就是,为什么 Python 计算集合的差集的时候时间复杂度是 O(n)呢? python 计算差集原理我不太了解

因为 golang 的官方并没有提供计算差集的库,我去网上看了一些第三方 golang 库的源码,实际上也是通过嵌套循环来实

现集合计算差集的,并且这种嵌套循环在数据量比较大的时候,cpu 占用也并不是太高
neoblackcap
2019-07-17 15:43:09 +08:00
@Buffer2Disk
简单的理解就是只是用其中迭代其中一个集合,然后判断一下这个元素是否在,每次查询是否在集合的操作是 O(1),n 个就是 O(n)
Buffer2Disk
2019-07-17 17:07:30 +08:00
@neoblackcap 网上那些 golang 的第三方库, 判断一下这个元素是否在 的这个操作(contains),内部实现也是一个循环,所以实际上也就变成了 2 个循环在叠代

python 我不清楚是怎么个实现法儿的
Buffer2Disk
2019-07-17 18:00:17 +08:00
@neoblackcap
我尝试了下,golang 里面用 map 这种哈希结构的集合来存储数据,它判断元素是否存在的时间复杂度也是 O(1)
使用之后,cpu 的消耗 比 单纯的用 for 循环来迭代降下来不少

所以伪代码就是这样
for i in list {
if map[i] != null {
//存在
}
}

两个 6000 个元素的集合情况下
map 时间复杂度 O(n) , cpu 消耗 1%
for 循环迭代 O(n^2) ,cpu 消耗 4%

在元素比较多的情况,map 这种能够快速检索 key 的结构还是有优势的
neoblackcap
2019-07-17 18:27:04 +08:00
@Buffer2Disk 本身集合一般就是用哈希表实现
Buffer2Disk
2019-07-17 18:31:02 +08:00
@neoblackcap 没有啊,golang 里面的 list 就是双向链表实现的 = =
way2create
2019-07-17 23:29:00 +08:00
看见这个帖子...我想起曾经某语言某性能网站上的代码拿到本地一测,调换下测试顺序,结果完全不同了...所以严重怀疑那个网站测试的真实性

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

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

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

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

© 2021 V2EX