17

Go1.14为time.Timer定时器带来巨幅性能提升

 4 years ago
source link: http://www.pengrl.com/p/20021/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

先看标准库中的time package benchmark的指标变化:

Changes in the time package benchmarks:

name                      old time/op  new time/op  delta
AfterFunc-12              1.57ms ± 1%  0.07ms ± 1%  -95.42%  (p=0.000 n=10+8)
After-12                  1.63ms ± 3%  0.11ms ± 1%  -93.54%  (p=0.000 n=9+10)
Stop-12                   78.3µs ± 3%  73.6µs ± 3%   -6.01%  (p=0.000 n=9+10)
SimultaneousAfterFunc-12   138µs ± 1%   111µs ± 1%  -19.57%  (p=0.000 n=10+9)
StartStop-12              28.7µs ± 1%  31.5µs ± 5%   +9.64%  (p=0.000 n=10+7)
Reset-12                  6.78µs ± 1%  4.24µs ± 7%  -37.45%  (p=0.000 n=9+10)
Sleep-12                   183µs ± 1%   125µs ± 1%  -31.67%  (p=0.000 n=10+9)
Ticker-12                 5.40ms ± 2%  0.03ms ± 1%  -99.43%  (p=0.000 n=10+10)
Sub-12                     114ns ± 1%   113ns ± 3%     ~     (p=0.069 n=9+10)
Now-12                    37.2ns ± 1%  36.8ns ± 3%     ~     (p=0.287 n=8+8)
NowUnixNano-12            38.1ns ± 2%  37.4ns ± 3%   -1.87%  (p=0.020 n=10+9)
Format-12                  252ns ± 2%   195ns ± 3%  -22.61%  (p=0.000 n=9+10)
FormatNow-12               234ns ± 1%   177ns ± 2%  -24.34%  (p=0.000 n=10+10)
MarshalJSON-12             320ns ± 2%   250ns ± 0%  -21.94%  (p=0.000 n=8+8)
MarshalText-12             320ns ± 2%   245ns ± 2%  -23.30%  (p=0.000 n=9+10)
Parse-12                   206ns ± 2%   208ns ± 4%     ~     (p=0.084 n=10+10)
ParseDuration-12          89.1ns ± 1%  86.6ns ± 3%   -2.78%  (p=0.000 n=10+10)
Hour-12                   4.43ns ± 2%  4.46ns ± 1%     ~     (p=0.324 n=10+8)
Second-12                 4.47ns ± 1%  4.40ns ± 3%     ~     (p=0.145 n=9+10)
Year-12                   14.6ns ± 1%  14.7ns ± 2%     ~     (p=0.112 n=9+9)
Day-12                    20.1ns ± 3%  20.2ns ± 1%     ~     (p=0.404 n=10+9)

数据来源: https://github.com/golang/go/commit/6becb033341602f2df9d7c55cc23e64b925bbee2

从基准测试结果中可以看到,After函数从老版本的1.63ms直接下降到了0.11ms,提升相当恐怖。

我个人对于此次优化的粗浅理解是:

在1.14之前,标准库会在在创建Timer时懒创建goroutinue,全局最多创建64个,这些goroutinue创建好后永远不会退出,每个goroutinue中有一个最小堆,管理着一部分定时器,这些goroutinue会给Go的线程调度模型带来非常大的开销。

而1.14则直接在P上管理Timer,这样调度器在每次调度循环的间隙都可以检查是否有超时的timer需要执行,并且可以通过netpoll进行唤醒,有点类似于epoll的事件驱动模型中的定时器管理。

具体的分析可以看欧长坤大佬对于Go 1.14定时器优化的分析:

原文链接: https://pengrl.com/p/20021/

原文出处: yoko blog ( https://pengrl.com )

原文作者: yoko ( https://github.com/q191201771 )

版权声明:本文欢迎任何形式转载,转载时完整保留本声明信息(包含原文链接、原文出处、原文作者、版权声明)即可。本文后续所有修改都会第一时间在原始地址更新。

yUJjmuq.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK