內(nèi)存分配會(huì)產(chǎn)生多大開銷?
寫c艸的人,似乎都不太愿意new東西出來。大家認(rèn)為new是開銷很大的操作。大家能把結(jié)構(gòu)體放在棧上,一般就不愿意把它放在堆上。即使是不得不放在堆上,不少的項(xiàng)目中也會(huì)使用各種各樣的內(nèi)存池來管理這些內(nèi)存。
如果某個(gè)函數(shù)需要輸出一個(gè)結(jié)構(gòu)體作為結(jié)果,那么寫c艸的人一定會(huì)把這個(gè)輸出結(jié)構(gòu)體放到函數(shù)的參數(shù)中,讓調(diào)用方在棧上分配這個(gè)結(jié)構(gòu)體,然后把它作為參數(shù)傳遞給函數(shù)。寫c艸的人絕不會(huì)new一個(gè)對(duì)象然后返回它的unique_ptr,反正我是從來沒有見過這種東西。
那么問題來了,我們苦心避免的內(nèi)存分配開銷,到底是多大的一個(gè)開銷?說實(shí)話,我也很好奇。百度了一圈,又谷歌了一圈,都沒有找到滿意的答案。于是我寫了一個(gè)簡單的程序來進(jìn)行測試。測試的結(jié)果是一對(duì)分配+釋放操作大約需要150ns左右。
測試用的內(nèi)存分配器用的是windows默認(rèn)的那個(gè),即微軟ucrt里面的分配器,測試程序沒有多線程的case。
這個(gè)測試中,內(nèi)存分配的大小和內(nèi)存釋放的時(shí)間都是隨機(jī)的。測試時(shí),每次申請(qǐng)的內(nèi)存在16字節(jié)到256字節(jié)之間隨機(jī)。測試的流程是先分配一萬次內(nèi)存,接下來每次分配內(nèi)存時(shí)隨機(jī)挑選一個(gè)未釋放的內(nèi)存釋放。最后釋放掉所有內(nèi)存。也就是說,測試期間大部分時(shí)候,保持有一萬塊已分配但未釋放的內(nèi)存用來保證內(nèi)存中有足夠多的“碎片”。同時(shí)還有一個(gè)對(duì)照組。對(duì)照組執(zhí)行同樣的邏輯,但是不會(huì)執(zhí)行內(nèi)存分配和釋放。比較實(shí)驗(yàn)組和對(duì)照組之間耗時(shí)的差值來得到內(nèi)存分配的凈用時(shí)。
我會(huì)把這個(gè)代碼扔到github上。見評(píng)論區(qū)置頂。