看看几个数字,
- MacBook 2018, 4 core, 2.3GHz;
- SSD的磁盘读取效率是 r 550M/s; w 500M/s
- 内存的读写效率是 2400MHz; 2.4GHz
2.3GHz, 为 1秒可以计算 2.3*1000*1000*1000次, 每个操作在0.7ns;
且go在循环内部增加多个变量的循环,与一个递增的值一致;
相关参数的值
光速, 299 792 458 m / s , 北京到上海的距离是 1500KM * 2(折射) 约 0.01s = 10ms,因此涉及到交易往返, 约 30~40ms
总结
- golang还可以通过pprof来监控;
- C 语言的一次操作约等于一个处理频率;
- golang的一次操作约等于0.63,应该外部封装后调用系统内核
- 多个变量在一个内部不变;
- golang的一次mutex的操作时间是 33 30ns / 2 约 15ns;
说明 | 效率 | 说明 |
---|---|---|
C的一次操作 | 一个CPU主频,0.7ns | 本机数据 |
golang的一次操作 | 不太准 0.15ns | 待深入研究 |
CPU访问L1 cache | 0.5ns | 待理解 |
分钟预测失败 | 5ns | 不明白 |
CPU访问L2 cache | 7ns | 待理解 |
内存访问 | 100ns | 待验证 |
千兆网送1M数据 | 10ms | 待验证 |
内存读取1M数据 | 0.25ms | 待验证 |
异地机房来回 | 30~100ms | 理论验证(光速) |
SATA磁盘寻道 | 10ms | 书本多次以10ms计算 |
SSD访问延迟 | 0.1~0.2ms | 待理解 |
案例1 C
经过多次计算约每秒执行710,000,000次;
for循环 n次比较、i++、s+=1; , 一次i++, 一次 s+=1; 2300/710 = 3.1次
案例1 go
可以计算3,600,000,000次;
for循环 n次比较、i++、s+=1; , 一次i++, 一次 s+=1; 2300/3600 ~ 0.63 次
不知道go内部对于递增的情况的内部优化情况,需要通过汇编层进一步了解;
案例2 C
多次计算后每秒执行约 590,000,000次;
for循环 n次比较、i++、s+=1; n+=1; m+=1; 5次操作 2300/590 ~ 3.9次
执行了一次printf("%d\n", n)
案例2 go
go 依然可以计算 3,600,000,000 次;
for循环 n次比较、i++、s+=1; n+=1; m+=1; 5次操作 2300/3600 ~ 0.63, 多个变量无影响;
案例3
多次计算后每秒执行约 450,000,000次;
for循环 n次比较、i++、s+=1; n+=1 m+=1; o+=1; p+=1; 7次操作 2300/450 ~ 5次;
#include <stdlib.h>
int main(int argc, char **argv) {
int NUMBER, i, s, n;
NUMBER = atoi(argv[1]);
n = 0;
for (s = i = 0; i < NUMBER; ++i) {
s += 1;
}
printf("%d\n", n)
return 0;
}
执行结果
zhaojjs-MacBook-Pro:ctest zhaojj$ time ./test 710000000
real 0m0.993s
user 0m0.986s
sys 0m0.004s
zhaojjs-MacBook-Pro:ctest zhaojj$ time ./test 710000000
real 0m1.003s
user 0m0.995s
sys 0m0.005s
zhaojjs-MacBook-Pro:ctest zhaojj$ time ./test 710000000
real 0m1.004s
user 0m0.992s
sys 0m0.006s
golang 代码
package main
import (
"os"
"strconv"
)
func main() {
var n, m, o, p,r,s,t,v,u,w int
// NUM1 := os.Args[1]
NUM, _ := strconv.Atoi(os.Args[1])
for i := 0; i < NUM; i++ {
n = n + 1
m = m + 1
o = o + 1
p = p + 1
}
}
执行结果
zhaojjs-MacBook-Pro:goperform zhaojj$ time ./goperform 3600000000
real 0m0.995s
user 0m0.988s
sys 0m0.005s
zhaojjs-MacBook-Pro:goperform zhaojj$ time ./goperform 3600000000
real 0m1.006s
user 0m1.000s
sys 0m0.005s
go mutex的操作
package main
import (
"os"
"strconv"
"sync"
)
var m sync.Mutex
func main() {
var n, o, p int
// NUM1 := os.Args[1]
NUM, _ := strconv.Atoi(os.Args[1])
p = NUM
for i := 0; i < NUM; i++ {
m.Lock()
o = o + 1
p = p + 1
n = n + 1
m.Unlock()
}
}
执行结果
zhaojjs-MacBook-Pro:goperform zhaojj$ time ./goperform 72000000
real 0m1.006s
user 0m0.989s
sys 0m0.007s
zhaojjs-MacBook-Pro:goperform zhaojj$ time ./goperform 72000000
real 0m0.996s
user 0m0.990s
sys 0m0.004s
参考资料
计算机一秒做的内容
大规模分布式存储系统
Custom pprof profiles
Profiling Go programs with pprof
剖析与优化 Go 的 web 应用