為什麼STL沒有提供通用的小物件優化(SSO SBO SOO Arena等)的實現?

時間 2021-06-03 03:53:10

1樓:Dot Blue

綜合來說,一部分是歷史原因,一部分是通用實現難以達到內部實現的效果。

SSO(Small Size Optimization)出現的目的無非是讓小物件的記憶體往棧上而不是堆上放。如果有SSO和無SSO的差別僅僅是是否根據分配大小決定存放的地方不同,那通用的SSO就應該通過分配器allocator實現。

然而。。allocator幾乎是C++中設計的最混亂的一塊,在C++11以前的allocator是無狀態的,這就決定了allocator實現不了local arena。C++11以後allocator可以有狀態了,但要寫一堆複雜的allocator_traits。

直到C++17後加入的pmr以執行時多型的開銷讓寫allocator變得簡單。

不過allocator難寫是寫STL的人的事,與我們無關。理論上C++11後都可以實現帶SSO優化的allocator(allocator內部放一小塊buffer,分配空間小於buffer size返回buffer的位址,否則轉上一級allocator分配),對於所有能自定allocator的物件,丟個帶SSO優化的allocator進去就能實現SSO。

然而問題並沒有完全解決…

一方面是不少STL的物件根本不鳥allocator,比如std::any,std::function(它本來是支援allocator的,但由於實現的參差不齊,委員會在C++17中移除了對allocator的支援→_→)

另一方面是,對於某些要用SSO的物件,對於空間是能計較到乙個位元組的。比如basic_string裡SSO的實現,都是把capacity、pointer和small buffer用union結合到一起,用size判斷是存堆上還是棧上,又壓縮出了兩個變數的空間。為了壓縮出這麼一點點的空間,不同物件可能採用的是完全不同的方法

如果僅僅替換了allocator來實現SSO,就難以壓縮出這一點空間。如果通用的SSO allocator空間利用率沒有內部實現的好,那為啥還要用它呢:D

2樓:d41d8c

STLGNUISO C++

建議把主體先選好。乙個問題出現三個不同主體有點讓人迷惑。

SSO/SBO只是個概念,語言上並沒有具體的設施來支援它的實現。

目前相比於實現通用模組,根據具體情境分別定義省事多了。

對於題主給的三個例子(string/function/any)string需要追蹤陣列大小,根據大小選擇儲存方式。function和any只需要在構造/賦值時選擇。

function和any雖說都是type erasure,但是具體需求有所不同,比如二者的建構函式有不同的要求。

即使function和any使用共同的SSO/SBO模組,也免不了type erasure和各種細節上的麻煩,還多了需要維護共同模組的負擔。實現者大概是覺得並不值得。

3樓:暮無井見鈴

啊我把第二個 S 當成 string 了,下面的回答可能會不切題。

一部分是歷史原因,另外一部分原因不明。

STL 目前缺 small_vector ( boost 有),這個東西專門應對 SSO 。

擁有獨佔所有權的 basic_string 應該做成乙個容器介面卡,以適配各種 contiguous containers ,如 vector 和 small_vector 。從而底層的儲存容器也能為使用者單獨拿出來使用。

但是古代 C++ 的 basic_string 允許引用計數實現,不好做成容器介面卡。 C++11 出於原始碼級相容沒有改動這點。

不知為何 C++ 標準庫很長時間以來都沒考慮過加容器。 C++11 的無序關聯容器是原始 STL 就有的,而 std::array 也在 TR1 就有了。

4樓:jencol teng

侯捷先生在《STL原始碼剖析》上介紹過的「小型物件分配技術」,並剖析了乙個記憶體池。

目前的GCC(至少在4.8以後)都有該記憶體池的實現,但是預設使用的是new/delete,也就是把記憶體控制功能交給了C。

為什麼客家話沒有粵語通用?

經濟原因,就像為什麼全世界都在用英語一樣,經濟決定文化強弱。客家人本就是為了避難,所以定居在山區的多,經濟並不發達,不能做文化輸出,造成影響力。粵語在珠三角一帶,依靠香港 廣州 深圳,粵語電影 歌曲等文化都發展的非常好,其他語系的人也能說幾句台詞哼兩句歌,更不用說粵語本地及周邊的,本身粵語活著類粵語...

為什麼STL的很多container的range version insert函式實現都有input iterator和forward iterator兩個過載?

QAMichaelPeng 以vector insert const iter where,iter first,iter last 為例,如果引數為forward iter,則可以多次遍歷訪問。先用一次遍歷訪問求出待插入元素個數,預分配好記憶體,就可以減少記憶體分配的開銷。而input itera...

為什麼現在的作業系統都沒有提供對農曆的原生支援?

言簡意賅 農曆是天文歷 格里曆 公曆 是計算歷。天文歷需要實測,公曆可以計算。可計算和不可計算,才是計算機的難點。農曆根據精確的實測的此刻,能精確估算以後一少部分,優點是幾乎無誤差,缺點是無固定規律,不能推算很遠,需要經常地測量天文。公曆算出了幾百年的平均值,估算以後很遠的平均值,優點有規律可循便於...