<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 從版本 1.0 到 1.22的性能變化

          共 2566字,需瀏覽 6分鐘

           ·

          2024-04-18 09:40

          兩年前,我在 1.2 到 1.18 的所有 Go 版本上比較了 GoAWK 解釋器的兩個(gè)不同基準(zhǔn)。

          在本文中,我重新運(yùn)行這些基準(zhǔn)測試,添加缺少的 Go 版本(1.0 和 1.1)以及新版本(1.19 到 1.22)。我還包含了 Go 1.20 中添加的配置文件引導(dǎo)優(yōu)化 (PGO) 的結(jié)果。我將引用我原來文章中的一些內(nèi)容,這樣您就不必重新閱讀舊文章來理解設(shè)置。

          用 Go 編寫的程序可以通過多種方式變得更快:Go 團(tuán)隊(duì)和外部貢獻(xiàn)者改進(jìn)了編譯器,并優(yōu)化了運(yùn)行時(shí)、垃圾收集器和標(biāo)準(zhǔn)庫。在這里,我們比較了使用 Go 的每個(gè)發(fā)布版本(從 1.0 到 1.22)(撰寫本文時(shí)的最新版本)編譯時(shí) GoAWK 的性能。

          我通過在兩個(gè) AWK 程序上運(yùn)行 GoAWK 來測試這一點(diǎn),這兩個(gè)程序代表了使用 AWK 可以執(zhí)行的不同極端操作:帶有字符串處理的 I/O 和數(shù)字運(yùn)算。

          首先,我們有 countwords ,一個(gè)字符串處理任務(wù),它計(jì)算輸入中單詞的頻率并打印出單詞及其計(jì)數(shù)。這是 AWK 腳本的典型情況。輸入是 King James Bible 的 10 倍串聯(lián)版本(我之前用過它來進(jìn)行性能比較)。代碼如下:

          {    for (i=1; i<=NF; i++)        counts[tolower($i)]++}
          END { for (k in counts) print k, counts[k]}

          第二個(gè)程序是 sumloop ,一個(gè)緊密循環(huán),它將循環(huán)計(jì)數(shù)器多次添加到變量中。這實(shí)際上并不是 AWK 的典型用法,但可以很好地測試 GoAWK 字節(jié)碼解釋器循環(huán):

          BEGIN {    for (i=0; i<10000000; i++)        sum += i+i+i+i+i}

          我必須稍微調(diào)整 GoAWK 的代碼才能使其在較舊的 Go 版本上進(jìn)行編譯。特別是對于 Go 1.0,因?yàn)樗鼪]有 bufio.Scanner ,而 GoAWK 大量使用它。我在 1.0 中使用了 bufio.Scanner 的 Go 1.1 實(shí)現(xiàn)。

          圖表中的計(jì)時(shí)數(shù)字是我的 x86-64 Linux 筆記本電腦上的時(shí)間(以秒為單位)(三輪運(yùn)行中最好的)。藍(lán)線是 countwords ,紅線是 sumloop (順便說一句,我上次錯(cuò)誤地標(biāo)記了結(jié)果)。請注意,這次 Y 軸是對數(shù)的,以便更清楚地看到最近版本中更微妙的改進(jìn)。

          圖表中還包括每個(gè) Go 版本的 GoAWK 二進(jìn)制大小 - 即淺灰色線。

          我再次使用 Python 腳本來運(yùn)行它們并測量時(shí)間。這是圖表(如果您愿意,也可以作為表格):

          最大的改進(jìn)來自版本 1.3、1.5、1.7 和 1.12。之后,速度會逐漸加快——所有容易實(shí)現(xiàn)的目標(biāo)都早已被采摘了。

          這次,Go 1.2 中的 countwords 出現(xiàn)了奇怪的變化:它從 1.1 中的 7.5 秒增加到 1.2 中的 25.5 秒(?。缓笤?1.3 中下降到 2.8 秒。這幾乎肯定是由堆?!盁岱指睢眴栴}引起的,該問題在 1.3 中得到了修復(fù),因?yàn)?Go 團(tuán)隊(duì)將“goroutine 堆棧的實(shí)現(xiàn)從舊的‘分段’模型更改為連續(xù)模型”。

          我通過分析找出了 1.2 異常的原因,并注意到運(yùn)行時(shí)堆棧操作占了運(yùn)行時(shí)間的很大一部分。這是 pprof 輸出的前幾行:

          $ go tool pprof --text ./goawk_1.2 go12.prof Total: 1830 samples     332  18.1%  18.1%      332  18.1% runtime.newstack     296  16.2%  34.3%      296  16.2% runtime.memclr     281  15.4%  49.7%      281  15.4% runtime.oldstack     222  12.1%  61.8%      619  33.8% github.com/benhoyt/goawk/interp.(*interp).execute      91   5.0%  66.8%       91   5.0% runtime.lessstack      75   4.1%  70.9%      133   7.3% github.com/benhoyt/goawk/interp.(*interp).callBuiltin      57   3.1%  74.0%       57   3.1% runtime.stackfree      53   2.9%  76.9%       81   4.4% strings.FieldsFunc      ...

          使用 Go 1.22,PGO 僅提高了幾個(gè)百分點(diǎn)的性能, countwords 大約提高了 2%, sumloop 提高了 7%。我使用 PGO 編譯發(fā)布的 GoAWK 二進(jìn)制文件。

          除了 1.2 中的大幅增長之外,多年來二進(jìn)制大小一直保持相當(dāng)穩(wěn)定。即使啟用了 PGO,二進(jìn)制文件也只會大 5% 左右,所以我認(rèn)為這通常是值得的。

          總體而言, countwords 現(xiàn)在的速度大約是 Go 1.0 的 8 倍, sumloop 的速度是 Go 1.0 的 24 倍。感謝Go團(tuán)隊(duì)多年來的辛勤付出!

          瀏覽 165
          10點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          10點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  百度一下黑人巨鸡干处女 | 亚洲欧美日韩豆花 | 欧美老熟妇乱大交XXXXX动漫 | 久久黄色视 | 日韩乱码人妻无码超清蜜桃丨 |