在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

只改變一個(gè)字符使Go程序提速42%

馬哥Linux運(yùn)維 ? 來(lái)源:量子位 ? 作者:量子位 ? 2022-11-24 15:48 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Go語(yǔ)言本來(lái)就以輕量快速著稱(chēng),一位GitHub員工卻偶然發(fā)現(xiàn):

只改變一個(gè)字符的位置,能把一段代碼運(yùn)行速度提高足足42%。

e60973ee-6b35-11ed-8abf-dac502259ad0.png

簡(jiǎn)直就像是……

e61cb9cc-6b35-11ed-8abf-dac502259ad0.png

這個(gè)簡(jiǎn)單有效的技巧一經(jīng)發(fā)布,就引來(lái)眾多程序員圍觀。

原作者自己也調(diào)侃,一般這種情況都是事先犯了個(gè)愚蠢的錯(cuò)誤,后面才能提升這么大。

不過(guò)順著這個(gè)思路發(fā)現(xiàn)有人發(fā)現(xiàn),就連Go開(kāi)發(fā)團(tuán)隊(duì)的核心人物Russ Cox都在標(biāo)準(zhǔn)庫(kù)中犯過(guò)同樣的錯(cuò)誤。

e62da426-6b35-11ed-8abf-dac502259ad0.png

什么樣的錯(cuò)誤?

發(fā)現(xiàn)這個(gè)問(wèn)題的Harry在大型程序員交友平臺(tái)GitHub工作。

他在開(kāi)發(fā)一個(gè)把GitHub倉(cāng)庫(kù)中每個(gè)文件的所有者列出來(lái)的小工具。

功能很簡(jiǎn)單,就是根據(jù)CODEOWNERS文件中定義的規(guī)則匹配,寫(xiě)在越下面的規(guī)則優(yōu)先級(jí)越高。

e6596aac-6b35-11ed-8abf-dac502259ad0.png

原理也很簡(jiǎn)單,就是從后往前一條一條處理,匹配到了就停止。

e66c4546-6b35-11ed-8abf-dac502259ad0.png

但就是這樣一個(gè)簡(jiǎn)單的程序卻出現(xiàn)了性能問(wèn)題,處理中等大小的倉(cāng)庫(kù)就很慢了。

e6894498-6b35-11ed-8abf-dac502259ad0.png

他打印出火焰圖,發(fā)現(xiàn)大部分時(shí)間都花在了Go語(yǔ)言的正則表達(dá)式引擎中。

另外在內(nèi)存動(dòng)態(tài)分配malloc和垃圾回收gc上面的花費(fèi)也值得注意。

e69a928e-6b35-11ed-8abf-dac502259ad0.png

要減少malloc的時(shí)間,就需要用到Go語(yǔ)言的逃逸分析(Escape Analysis)了。

簡(jiǎn)單來(lái)說(shuō),就是盡量把變量分配到棧上,讓編譯器自動(dòng)管理內(nèi)存的釋放。

只有在“逃逸”也就是變量的作用域超出所在的棧時(shí),才把變量分配到堆上,減輕運(yùn)行時(shí)GC的壓力。

在這次的程序中,Harry確定了逃逸的變量是rule這個(gè)結(jié)構(gòu)體(struct)。

e6ad0fcc-6b35-11ed-8abf-dac502259ad0.png

但問(wèn)題是,rule存儲(chǔ)在RuleSet這個(gè)切片(slice)里,按Go語(yǔ)言的規(guī)則可以確信他已經(jīng)在堆中了。

再分析一下代碼,發(fā)現(xiàn)在給rule賦值的時(shí)候?qū)嶋H上是做了一次不必要的拷貝,后面用“&”取地址時(shí)候創(chuàng)建了一個(gè)逃逸的指針指向它的副本。

e6c1220a-6b35-11ed-8abf-dac502259ad0.png

最后解決辦法也很容易想出,只需要把&移動(dòng)到上面。

e6d2be98-6b35-11ed-8abf-dac502259ad0.png

這樣就引用了切片中的結(jié)構(gòu)體,避免了拷貝。

如何徹底避免?

在熱議中,有網(wǎng)友分享了自己是怎么避免出現(xiàn)這個(gè)問(wèn)題的。

對(duì)于每個(gè)結(jié)構(gòu)體,把它看作純值或純指針,壓根就不去使用&這種取地址的操作,避免隱式的內(nèi)存分配。

e6f17946-6b35-11ed-8abf-dac502259ad0.png

如果你想要深入理解這個(gè)問(wèn)題,也有人貼心的給出了需要提前了解的一些背景知識(shí)。

e705e700-6b35-11ed-8abf-dac502259ad0.png

最后有人指出,Rust語(yǔ)言為避免這個(gè)問(wèn)題,直接規(guī)定必須顯式操作才能拷貝一個(gè)數(shù)據(jù)結(jié)構(gòu)。

e719c388-6b35-11ed-8abf-dac502259ad0.png

當(dāng)你不習(xí)慣的時(shí)候這規(guī)定煩得要命,但是總的來(lái)看還是值得。

方便or規(guī)范,你更傾向于哪種做法?

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4899

    瀏覽量

    70594
  • go語(yǔ)言
    +關(guān)注

    關(guān)注

    1

    文章

    159

    瀏覽量

    9360

原文標(biāo)題:只改變一個(gè)字符使 Go 程序提速 42%

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    使用S32K322上的LPUART進(jìn)行UART通信,接收超過(guò)14個(gè)字符時(shí)遇到問(wèn)題,求解決

    我正在使用 S32K322 上的 LPUART 進(jìn)行 UART 通信,并在接收超過(guò) 14 個(gè)字符時(shí)遇到問(wèn)題。具體來(lái)說(shuō),在調(diào)用 Lpuart_Uart_Ip_GetReceiveStatus我收到錯(cuò)誤
    發(fā)表于 03-28 07:00

    ADS1274用DRDY+TDM輸出模式下,讀到的第一個(gè)字節(jié)是無(wú)效的,為什么?

    今天調(diào)試中發(fā)現(xiàn)個(gè)問(wèn)題,1274在用DRDY+TDM輸出模式下,讀到的第一個(gè)字節(jié)是無(wú)效的! 配置是4通道,在DRDY下降沿產(chǎn)生后,等待5us(采樣率25K,即間隔40us)給出SPI的SCLK
    發(fā)表于 01-08 08:17

    字符串反轉(zhuǎn)的實(shí)現(xiàn)方式

    在編程中,字符串反轉(zhuǎn)是個(gè)基礎(chǔ)而重要的操作,它涉及到將一個(gè)字符串中的字符順序顛倒過(guò)來(lái)。這個(gè)操作在多種編程語(yǔ)言中都有不同的實(shí)現(xiàn)方式,本文將探討
    的頭像 發(fā)表于 01-07 15:27 ?808次閱讀

    C語(yǔ)言筆試題

    。 函數(shù) g 輸出一個(gè)字符串,返回整數(shù) 2。 主函數(shù)中用 printf 輸出兩個(gè)函數(shù)的函數(shù)值,后面的參數(shù)一個(gè)是函數(shù) f,一個(gè)是函數(shù) g。 運(yùn)行程序
    的頭像 發(fā)表于 12-30 09:48 ?411次閱讀

    飛凌嵌入式ElfBoard ELF 1板卡-提示程序之提示腳本continue.sh

    [0m\"表示重置文本顏色。接下來(lái)進(jìn)入個(gè)無(wú)限循環(huán),每次循環(huán)使用read命令讀取用戶(hù)輸入的一個(gè)字符,并使用選項(xiàng)-s和-n來(lái)隱藏輸入字符并不換行。如果讀取到的
    發(fā)表于 12-07 08:52

    stm32/gd32 wifi模塊通信異常問(wèn)題

    的,wifi模塊都回復(fù)一個(gè)字符,這個(gè)字符還是發(fā)送指令中的任意個(gè)(發(fā)送\"AT\",回\"A\"或\"T\"),有時(shí)候干脆回復(fù)\"erro
    發(fā)表于 10-21 08:59

    鴻蒙原生應(yīng)用元服務(wù)開(kāi)發(fā)-倉(cāng)頡基礎(chǔ)數(shù)據(jù)類(lèi)型字符類(lèi)型

    對(duì)單引號(hào)或雙引號(hào)包含的字符。 單個(gè)字符字符字面量舉例: let a: Rune = r\'a\' let b: Rune = r\"b\" 轉(zhuǎn)義
    發(fā)表于 09-19 10:58

    MATLAB(5)--字符串處理

    字符串表示 在MATLAB中,字符串是用單引號(hào)括起來(lái)的字符序列,是把一個(gè)字符串當(dāng)做一個(gè)行向量,這個(gè)行向量中,每個(gè)元素對(duì)應(yīng)
    發(fā)表于 09-06 10:22

    labview字符串?dāng)?shù)組轉(zhuǎn)化為數(shù)值數(shù)組

    常重要的。LabVIEW支持多種數(shù)據(jù)類(lèi)型,包括數(shù)值、字符串、數(shù)組、簇等。在本例中,我們將關(guān)注字符串?dāng)?shù)組和數(shù)值數(shù)組。 字符串?dāng)?shù)組 :由系列字符
    的頭像 發(fā)表于 09-04 17:47 ?5502次閱讀

    嵌入式學(xué)習(xí)-飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫(xiě)之傳參

    腳本,并傳入?yún)?shù)par1和par2:2、獲取傳遞參數(shù)獲取傳遞參數(shù)的個(gè)數(shù)使用$#。在腳本中加入echo $#,打印出輸入?yún)?shù)的個(gè)數(shù):保存后執(zhí)行腳本,并傳入?yún)?shù)par1和par2:3、傳入的參數(shù)打包為一個(gè)字符
    發(fā)表于 09-03 14:26

    飛凌嵌入式ElfBoard ELF 1板卡-shell腳本編寫(xiě)之傳參

    腳本,并傳入?yún)?shù)par1和par2:2、獲取傳遞參數(shù)獲取傳遞參數(shù)的個(gè)數(shù)使用$#。在腳本中加入echo $#,打印出輸入?yún)?shù)的個(gè)數(shù):保存后執(zhí)行腳本,并傳入?yún)?shù)par1和par2:3、傳入的參數(shù)打包為一個(gè)字符
    發(fā)表于 09-02 09:39

    vim的操作方式有哪幾種

    模式下,用戶(hù)可以執(zhí)行各種命令來(lái)操作文本,例如移動(dòng)光標(biāo)、刪除文本、復(fù)制文本等。以下是命令模式下的些常用操作: 1.1 光標(biāo)移動(dòng) 在命令模式下,用戶(hù)可以使用以下按鍵來(lái)移動(dòng)光標(biāo): h:向左移動(dòng)一個(gè)字符 j:向下移動(dòng)一個(gè)字符 k:向上
    的頭像 發(fā)表于 08-30 14:54 ?940次閱讀

    vim的三種工作模式有哪些

    自動(dòng)進(jìn)入普通模式。在普通模式下,你可以使用各種快捷鍵來(lái)移動(dòng)光標(biāo)、復(fù)制、粘貼、刪除和查找文本等。 1.1 光標(biāo)移動(dòng) 在普通模式下,你可以使用以下快捷鍵來(lái)移動(dòng)光標(biāo): h:向左移動(dòng)一個(gè)字符 j:向下移動(dòng)一個(gè)字符 k:向上移動(dòng)一個(gè)字符
    的頭像 發(fā)表于 08-30 14:52 ?1582次閱讀

    請(qǐng)問(wèn)AT命令可以支持多少個(gè)字符?

    AT命令可以有多長(zhǎng)?當(dāng)輸入命令長(zhǎng)度超過(guò) 128 個(gè)字符時(shí),它看起來(lái) AT 自定義命令會(huì)中斷。
    發(fā)表于 07-16 06:17

    使用CIPDOMAIN命令時(shí),解析長(zhǎng)度為64個(gè)字符或更大的DNS名稱(chēng)失敗了,為什么?

    s3.dualstack.us-east-1.amazonaws.com 的CNAME記錄。 我轉(zhuǎn)儲(chǔ)了 libat.a 存檔并找到了at_setupcipomain函數(shù),似乎分配要在堆棧上復(fù)制的 64 字節(jié)的字符串。 首先,有人可以確認(rèn)這個(gè)限制嗎? 其次,我們能否獲
    發(fā)表于 07-11 07:59
    主站蜘蛛池模板: 亚洲国产精品婷婷久久 | 色爱区综合五月激情 | 日本一区二区三区欧美在线观看 | 香港经典a毛片免费观看爽爽影院 | 亚欧精品一区二区三区 | 猛操网| 久久久久久人精品免费费看 | 亚洲a区视频 | 激情亚洲综合网 | 亚洲操| 欧美aaaaaaaaa| 噜噜噜色网 | 天天色天天射天天操 | www.你懂的.com | 99精品视频在线播放2 | 永久看免费bbbbb视频 | 最新亚洲情黄在线网站 | 久久青草91线频免费观看 | 国产免费一区二区三区 | 激情五月婷婷久久 | 久久天天躁夜夜躁狠狠85麻豆 | 国产精品激情综合久久 | 亚洲成a人片在线观看导航 亚洲成a人片在线观看尤物 | 国产资源免费观看 | 亚洲综合精品一区二区三区中文 | 亚洲色图图片 | 欧美亚洲视频一区 | 国产精品久久久久久久久齐齐 | 一道精品视频一区二区三区男同 | 天天操操操操操操 | 四虎国产精品永久在线网址 | 不卡视频一区 | a天堂在线观看 | 人与禽一级一级毛片 | 日本特黄特色 | 午夜啪啪免费视频 | 久久精品亚洲精品国产色婷 | 亚洲视频在线播放 | 成人午夜大片免费视频77777 | 色老头综合 | 四级毛片在线播放 |