日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Golang數(shù)據(jù)結(jié)構(gòu)性能優(yōu)化實(shí)踐

來源: 責(zé)編: 時(shí)間:2024-01-02 09:30:41 198觀看
導(dǎo)讀如果你有Golang開發(fā)經(jīng)驗(yàn),一定定義過struct類型。但可能你不知道,通過簡單的重新排序struct字段,可以極大提高Go程序的速度和內(nèi)存使用效率!是不是難以置信?我們一起來看一下吧!簡單Demotype BadStruct struct { age

如果你有Golang開發(fā)經(jīng)驗(yàn),一定定義過struct類型。2z428資訊網(wǎng)——每日最新資訊28at.com

但可能你不知道,通過簡單的重新排序struct字段,可以極大提高Go程序的速度和內(nèi)存使用效率!2z428資訊網(wǎng)——每日最新資訊28at.com

是不是難以置信?我們一起來看一下吧!2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

簡單Demo

type BadStruct struct { age         uint8 passportNum uint64 siblings    uint16}type GoodStruct struct { age         uint8 siblings    uint16 passportNum uint64}

在上面的代碼片段中,我們創(chuàng)建了兩個(gè)具有相同字段的結(jié)構(gòu)體。然后編寫一個(gè)簡單程序分別輸出其內(nèi)存使用情況。2z428資訊網(wǎng)——每日最新資訊28at.com

// OutputBad struct is 24 bytes longGood struct is 16 bytes long

如你所見,它們?cè)趦?nèi)存使用方面并不一樣。2z428資訊網(wǎng)——每日最新資訊28at.com

是什么原因?qū)е聝蓚€(gè)完全相似的struct消耗的內(nèi)存不同?2z428資訊網(wǎng)——每日最新資訊28at.com

答案在于數(shù)據(jù)在計(jì)算機(jī)內(nèi)存中的排列方式。2z428資訊網(wǎng)——每日最新資訊28at.com

簡而言之,數(shù)據(jù)結(jié)構(gòu)對(duì)齊。2z428資訊網(wǎng)——每日最新資訊28at.com

數(shù)據(jù)結(jié)構(gòu)對(duì)齊

CPU以字(word)為單位讀取數(shù)據(jù),而不是字節(jié)(byte)。2z428資訊網(wǎng)——每日最新資訊28at.com

64位系統(tǒng)中,一個(gè)word是8個(gè)字節(jié),而32位系統(tǒng)中,一個(gè)word是4個(gè)字節(jié)。2z428資訊網(wǎng)——每日最新資訊28at.com

簡而言之,CPU以其字長的倍數(shù)讀取內(nèi)存地址。2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

想象一下,在64位系統(tǒng)中,為了獲取變量passportNum,CPU需要兩個(gè)周期來訪問數(shù)據(jù)。2z428資訊網(wǎng)——每日最新資訊28at.com

第一個(gè)周期將獲取內(nèi)存的0到7字節(jié),下一個(gè)周期獲取其余內(nèi)存字節(jié)。2z428資訊網(wǎng)——每日最新資訊28at.com

把它想象成一個(gè)筆記本,每頁只能存儲(chǔ)一個(gè)字大小的數(shù)據(jù)(在本例中為8字節(jié))。如果passportNum分散在兩個(gè)頁,則需要兩次讀取才能檢索到完整的數(shù)據(jù)。2z428資訊網(wǎng)——每日最新資訊28at.com

非常低效。2z428資訊網(wǎng)——每日最新資訊28at.com

因此需要數(shù)據(jù)結(jié)構(gòu)對(duì)齊,讓計(jì)算機(jī)將數(shù)據(jù)存儲(chǔ)在等于數(shù)據(jù)大小倍數(shù)的地址上。2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

4字節(jié)數(shù)據(jù)只能從內(nèi)存地址0或4開始2z428資訊網(wǎng)——每日最新資訊28at.com

例如,2字節(jié)數(shù)據(jù)可以存儲(chǔ)在內(nèi)存0、2或4中,而4字節(jié)數(shù)據(jù)可以存儲(chǔ)在內(nèi)存0、4或8中。2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

通過簡單的對(duì)齊數(shù)據(jù),計(jì)算機(jī)確??梢栽谝粋€(gè)CPU周期內(nèi)檢索到變量passportNum。2z428資訊網(wǎng)——每日最新資訊28at.com

數(shù)據(jù)結(jié)構(gòu)填充

填充是實(shí)現(xiàn)數(shù)據(jù)對(duì)齊的關(guān)鍵。2z428資訊網(wǎng)——每日最新資訊28at.com

計(jì)算機(jī)通過在數(shù)據(jù)結(jié)構(gòu)之間填充額外的字節(jié),從而對(duì)齊字段。2z428資訊網(wǎng)——每日最新資訊28at.com

這就是額外內(nèi)存的來源!2z428資訊網(wǎng)——每日最新資訊28at.com

我們來回顧一下BadStruct和GoodStruct。2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

GoodStruct消耗更少的內(nèi)存,僅僅因?yàn)榕cBadStruct相比,其struct字段順序更合理。2z428資訊網(wǎng)——每日最新資訊28at.com

由于填充,兩個(gè)13字節(jié)的數(shù)據(jù)結(jié)構(gòu)分別變成了16字節(jié)和24字節(jié)。2z428資訊網(wǎng)——每日最新資訊28at.com

因此,可以僅僅通過對(duì)struct字段重新排序來節(jié)省額外的內(nèi)存!2z428資訊網(wǎng)——每日最新資訊28at.com

這種優(yōu)化為什么重要?

問題來了,你為什么要關(guān)心這個(gè)?2z428資訊網(wǎng)——每日最新資訊28at.com

兩個(gè)方面,速度和內(nèi)存使用。2z428資訊網(wǎng)——每日最新資訊28at.com

我們做一個(gè)簡單的基準(zhǔn)測試來證明!2z428資訊網(wǎng)——每日最新資訊28at.com

func traverseGoodStruct() uint16 { var arbitraryNum uint16   for _, goodStruct := range GoodStructArr {  arbitraryNum += goodStruct.siblings }   return arbitraryNum}func traverseBadStruct() uint16 { var arbitraryNum uint16   for _, badStruct := range BadStructArr {  arbitraryNum += badStruct.siblings }   return arbitraryNum}func BenchmarkTraverseGoodStruct(b *testing.B) { for n := 0; n < b.N; n++ {  traverseGoodStruct() }}func BenchmarkTraverseBadStruct(b *testing.B) { for n := 0; n < b.N; n++ {  traverseBadStruct() }}

對(duì)GoodStruct和BadStruct進(jìn)行基準(zhǔn)測試的方法是循環(huán)遍歷數(shù)組,并將struct字段累加到變量中。2z428資訊網(wǎng)——每日最新資訊28at.com

2z428資訊網(wǎng)——每日最新資訊28at.com

從結(jié)果中可以看出,遍歷GoodStruct確實(shí)比BadStruct花費(fèi)時(shí)間更少。2z428資訊網(wǎng)——每日最新資訊28at.com

對(duì)struct字段重排序可以優(yōu)化應(yīng)用程序的內(nèi)存使用和速度。2z428資訊網(wǎng)——每日最新資訊28at.com

想象一下,維護(hù)一個(gè)具有大量結(jié)構(gòu)體的大型應(yīng)用程序,改變將會(huì)更為明顯。2z428資訊網(wǎng)——每日最新資訊28at.com

結(jié)語

好了,全文到此為止,我們以一個(gè)簡單的行動(dòng)呼吁來結(jié)束:一定要對(duì)struct結(jié)構(gòu)字段進(jìn)行重排序!2z428資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55105-0.htmlGolang數(shù)據(jù)結(jié)構(gòu)性能優(yōu)化實(shí)踐

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Go語言中的性能考慮和優(yōu)化

下一篇: “推薦大戰(zhàn):抖音vs.快手”——背后的秘密全揭曉!

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 安康市| 聊城市| 曲水县| 文水县| 遂溪县| 无为县| 沿河| 交口县| 山丹县| 平江县| 于都县| 呼伦贝尔市| 灵寿县| 鄂温| 兴山县| 商丘市| 关岭| 南昌市| 左贡县| 乌拉特中旗| 宁陵县| 甘德县| 通化市| 新化县| 会泽县| 建宁县| 田东县| 从江县| 长寿区| 股票| 阿克苏市| 南和县| 林西县| 西畴县| 丁青县| 望江县| 上虞市| 滦南县| 合山市| 峨边| 临泉县|