测试环境为
- MacBook Pro, i7 2.6GHz
- macOS 11.2.1
- Python 3.8.7
- Chrome 88.0.4324.150
- Go 1.15.7
使用Python、JavaScript、Go语言的for循环向列表(切片、数组)中循环添加100000000次,其中Go语言又分为数组不提前申请容量和提前申请容量两个版本。打印循环开始到结束耗时,单位为秒,保留6位小数。代码如下:
Python
import time
start = time.time()
#创建列表
i = []
#循环100000000次向该列表中添加成员
for num in range(100000000):
i.append(num)
#打印耗时
print("{:.6f}".format(time.time() - start))
JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const start = performance.now()
//创建数组
var array = []
//循环100000000次向该数组中添加成员
for (var i = 0; i < 100000000; i++) {
array.push(i)
}
//打印耗时
console.log(((performance.now() - start) / 1000).toFixed(6))
</script>
</body>
</html>
Go(len=0,cap=0)
package main
import (
"fmt"
"time"
)
func main() {
//创建长度、容量都为0的array并返回引用该array的切片
//同make([]int, 0)
slice := make([]int, 0, 0)
start := time.Now().UnixNano()
//循环100000000次向该切片中添加成员
for i := 0; i < 100000000; i++ {
slice = append(slice, i)
}
t := time.Now().UnixNano()
//打印耗时
fmt.Printf("%.6f\n", float64(t-start)/float64(time.Second))
}
Go(len=0,cap=100000000)
package main
import (
"fmt"
"time"
)
func main() {
//创建长度为0、容量为100000000的array并返回引用该array的切片
slice := make([]int, 0, 100000000)
start := time.Now().UnixNano()
//循环100000000次向该切片中添加成员
for i := 0; i < 100000000; i++ {
slice = append(slice, i)
}
t := time.Now().UnixNano()
//打印耗时
fmt.Printf("%.6f\n", float64(t-start)/float64(time.Second))
}
项目 | 耗时(s) |
---|---|
Python | 11.680694 |
JavaScript | 1.101530 |
Go(len=0,cap=0) | 1.531858 |
Go(len=0,cap=100000000) | 0.281574 |
Python和JavaScript都是解释型语言,所以非常相似,但同为解释器的CPython和V8性能就差的比较多了,CPython性能远弱于V8,可以参考:https://stackoverflow.com/a/5172833。
Go是编译型语言,速度自然没得说。但在初始化切片变量时有没有申请到足够容量的数组会对速度以及内存占用造成很大影响:如果append时切片引用的数组容量不足,则会重新申请容量更大的数组。所以最佳实践就是在变量初始化时就申请到足够容量的数组。