chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

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

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

掃碼添加小助手

加入工程師交流群

Go語言本來就以輕量快速著稱,一位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ā)布,就引來眾多程序員圍觀。

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

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

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

什么樣的錯(cuò)誤?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

但問題是,rule存儲(chǔ)在RuleSet這個(gè)切片(slice)里,按Go語言的規(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è)問題的。

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

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

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

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

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

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

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

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

審核編輯 :李倩

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

    關(guān)注

    30

    文章

    4947

    瀏覽量

    73214
  • go語言
    +關(guān)注

    關(guān)注

    1

    文章

    159

    瀏覽量

    9642

原文標(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)推薦

    串口超時(shí)中斷的原理與特點(diǎn)

    超時(shí)中斷 (Timeout Interrupt - RTO, Receiver Timeout) 觸發(fā)條件: 當(dāng)最后次成功接收到一個(gè)字符后(RXNE 事件后),在預(yù)設(shè)的超時(shí)時(shí)間內(nèi)沒有接收
    發(fā)表于 11-17 07:42

    飛凌嵌入式ElfBoard-標(biāo)準(zhǔn)IO接口之格式化輸入

    字符,格式說明符除外(%):任何不是空格字符(空白、換行符或制表符)或格式說明符(以%字符開頭)的字符都會(huì)導(dǎo)致函數(shù)從流中讀取下一個(gè)字符,將其
    發(fā)表于 11-12 08:35

    RISC-V的工具鏈GCC內(nèi)聯(lián)匯編

    ;;\"作為分隔符,沒有添加分隔符的兩個(gè)字符串會(huì)被合并成為一個(gè)字符串。“匯編指令列表”的編寫語法和普通的匯編程編寫是樣的。 4.\"輸入操作數(shù)\",用來指定當(dāng)前內(nèi)聯(lián)匯編程序的輸入
    發(fā)表于 10-30 06:59

    E203串口中斷使用總結(jié)

    () 開始重組數(shù)據(jù)。在這里,筆者假設(shè)通信不會(huì)丟包或者數(shù)據(jù)出錯(cuò),因此不設(shè)置通信協(xié)議,規(guī)定了數(shù)據(jù)包的大小。main() 中的代碼如下圖: 當(dāng)上位機(jī)用串口傳數(shù)據(jù)時(shí),會(huì)先從低位開始一個(gè)一個(gè)字符地傳,因此在接受
    發(fā)表于 10-22 07:34

    當(dāng)從接收DMA次接收一個(gè)字節(jié)時(shí),如何檢查是否已接收到任意長(zhǎng)度的所有數(shù)據(jù)包呢?

    當(dāng)從接收 DMA 次接收一個(gè)字節(jié)時(shí),如何檢查是否已接收到任意長(zhǎng)度的所有數(shù)據(jù)包?
    發(fā)表于 04-21 08:22

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

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

    ads7043如何保證在接收第一個(gè)字節(jié)時(shí)adc的第九位不會(huì)輸出?

    接收寄存器是8位 我在編程的時(shí)候遇到了問題 我想請(qǐng)問: 1. 如何保證在接收第一個(gè)字節(jié)時(shí)adc的第九位不會(huì)輸出?是通過調(diào)低spi串口的波特率來保證單片機(jī)程序運(yùn)行的時(shí)間嗎? 2. 因?yàn)閍dc輸出14位數(shù)
    發(fā)表于 01-13 08:23

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

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

    字符串在數(shù)據(jù)庫中的存儲(chǔ)方式

    數(shù)據(jù)庫是現(xiàn)代信息技術(shù)中存儲(chǔ)和管理數(shù)據(jù)的核心組件。字符串作為最常見的數(shù)據(jù)類型之,在數(shù)據(jù)庫中的存儲(chǔ)方式對(duì)其性能和可擴(kuò)展性有著重要影響。 數(shù)據(jù)類型 固定長(zhǎng)度字符串 :如CHAR類型,它為每個(gè)字符
    的頭像 發(fā)表于 01-07 15:41 ?1271次閱讀

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

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

    HDHG-F全功能互感器勵(lì)磁特性測(cè)試儀PT電壓互感器測(cè)試方法

    PT測(cè)試1.基本信息:存儲(chǔ)編號(hào):可輸入最多10個(gè)漢字或20個(gè)字符、字母和數(shù)字。繞組序號(hào):可輸入最多4個(gè)漢字或8個(gè)字符、字母和數(shù)字。建議采用預(yù)設(shè)值。繞組相序:表示當(dāng)前所測(cè)繞組的相序。可選
    的頭像 發(fā)表于 01-03 09:50 ?914次閱讀
    HDHG-F全功能互感器勵(lì)磁特性測(cè)試儀PT電壓互感器測(cè)試方法

    HDHG-1000P變頻互感器綜合測(cè)試儀PT電壓互感器測(cè)試方法

    PT測(cè)試1.基本信息:A.存儲(chǔ)編號(hào):互感器的編號(hào)。可輸入最多10個(gè)漢字或20個(gè)字符、字母和數(shù)字。B.繞組序號(hào):可輸入最多4個(gè)漢字或8個(gè)字符、字母和數(shù)字。建議采用預(yù)設(shè)值。C.繞組級(jí)別:被
    的頭像 發(fā)表于 01-02 10:27 ?1000次閱讀
    HDHG-1000P變頻互感器綜合測(cè)試儀PT電壓互感器測(cè)試方法

    HDHG-1000P變頻互感器綜合測(cè)試儀對(duì)CT電流互感器使用測(cè)試

    CT測(cè)試1.基本信息:A.存儲(chǔ)編號(hào):可輸入最多10個(gè)漢字或20個(gè)字符、字母和數(shù)字。B.繞組序號(hào):可輸入最多4個(gè)漢字或8個(gè)字符、字母和數(shù)字。建議采用預(yù)設(shè)值。C.繞組級(jí)別:被測(cè)的級(jí)別,對(duì)于
    的頭像 發(fā)表于 01-02 10:26 ?1001次閱讀
    HDHG-1000P變頻互感器綜合測(cè)試儀對(duì)CT電流互感器使用測(cè)試

    C語言筆試題

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

    養(yǎng)成良好的編程習(xí)慣|堆內(nèi)存初值不定是0

    ;} 代碼很簡(jiǎn)單,使用 malloc 申請(qǐng)段堆內(nèi)存,假設(shè)內(nèi)存空間足夠大。 通過 getchar 配合 while 循環(huán),從標(biāo)準(zhǔn)輸入獲取一個(gè)字符串,直到遇到換行符結(jié)束。 最后就是把獲取的字符串輸出。 乍
    的頭像 發(fā)表于 12-18 09:14 ?580次閱讀