成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

漫步Facebook開源C++庫Folly之string類設計

開發 后端
就在近日,Facebook宣布開源了內部使用的C++底層庫,總稱folly,包括散列、字符串、向量、內存分配、位處理等,以滿足大規模高性能的需求。

這里是folly的github地址:https://github.com/facebook/folly

在folly項目的Overview.md中,談到了folly庫的初衷:

It complements (as opposed to competing against) offerings such as Boost and of course std. In fact, we embark on defining our own component only when something we need is either not available, or does not meet the needed performance profile.

除了小部分是對現有標準庫和Boost庫功能上的補充,大部分都是基于性能的需求而“重新制造輪子”。

特別是大規模下的性能需求,大規模下的性能追求是Folly統一的主題:

Good performance at large scale is a unifying theme in all of Folly.

為什么先談string類?

一是因為string幾乎是C++程序中最常用的“容器”,性能至關重要;

二是因為之前也曾寫過一篇博客《std::string的Copy-on-Write:不如想象中美好》,研究了std::string的copy-on-write實現的優缺點,因此想要看看Facebook究竟需要什么樣的string。

folly自定義的string(以下簡稱為fbstring)的核心實現位于 folly/FBString.h。

還有一些fbstring的輔助函數(如向std::string的轉換、各種格式的輸出、escape、demangle等),位于 folly/String.h 和 folly/String.cpp ,由于本文主要談的是fbstring的內部實現,這些內容暫且不提,有興趣的童鞋可以自己參考源碼,folly的代碼還是寫得相當漂亮的:)

folly對string類的設計和優化,主要體現在兩個方面:

1. 內存模型

2. 常用方法的優化

下面將逐一說明。

一. 內存模型

1. 內存布局及策略

fbstring使用了三層的存儲策略(three-tiered storage strategy),根據長度將fbstring分為三類:small/medium/large,分別采取不同的優化措施,以達到最佳性能。

fbstring內存模型示意圖(使用LucidChart繪制):

 

簡單來說:

短string:直接放在(棧上)對象中,避免了動態內存分配的開銷。結構體長度為24字節,減去末尾的1字節(用來表示長度)和為結束符'\0'(data()和c_str()方法的需要)預留的1字節,可以放置22字節的有效長度。

中等string(小于255字節):直接通過malloc分配,并且采用eager-copy的方式,即字符串的復制總是會重新分配并拷貝內容。

至于為什么不用copy-on-write:

1. 我之前的博客也提到,copy-on-write的額外開銷(原子操作、容易失效)一定程度上抵消了減少一次內存分配和拷貝帶來的好處

2. folly鼓勵使用jemalloc來代替glibc下默認的ptmalloc2,并且在代碼中迎合jemalloc的使用做了大量優化。在這里,分配一個小片內存區域的開銷是極小的,下文還會有說明。

較長string(大于255字節):使用copy-on-write,減少分配和拷貝大內存的開銷。在這里,folly使用了C++11中的原子變量:std::atomic<size_t>來管理引用計數,并在引用計數減為0時銷毀內存。

PS:使用capacity最高位的4個bits來判斷string的種類,folly假定機器的字節序為小端(little endian),適用于x86-64平臺上的大部分OS。

2. 內存分配器

與std::string不同,fbstring并沒有從模板參數之一的Allocator獲取內存,而是直接使用malloc/free管理內存。

fbstring推薦使用jemalloc而不是Linux下glibc默認的ptmalloc2來管理動態內存:

1. 作為FreeBSD上的默認分配器,jemalloc在多線程并發的環境下表現更好(與google開源的tcmalloc性能相近)。

在tcmalloc的論文《TCMalloc : Thread-Caching Malloc》中,提到了ptmalloc2在多線程環境下的一個致命缺陷:

ptmalloc2同樣通過為不同的線程分配自己的內存池(Arena)的方式來減少并發分配時的鎖沖突,但ptmalloc2中線程擁有的內存池是不能遷移的,在某些情況下能夠帶來巨大的內存浪費:比如一個線程在開始階段分配了300MB的內存進行初始化工作,然后釋放了,但接下來的線程分配到不同的內存池,那么之前的300MB是無法重復利用的。

2. folly如果檢測到使用jemalloc,那么將使用jemalloc的一些非標準擴展接口來提高性能。

PS:folly通過定義弱符號(weak symbol)的方法來運行時判斷是否使用了jemalloc:

  1. extern "C" int rallocm(void**, size_t*, size_tsize_tint) __attribute__((weak));  
  2.  
  3. /**  
  4.  * Determine if we are using jemalloc or not.  
  5.  */ 
  6. inline bool usingJEMalloc() {  
  7.   return rallocm != NULL;  

如果使用了jemalloc,一個典型的優化是使用jemalloc特有的rallocm來代替標準的realloc方法。(下面還會提到realloc的優化)

同時,所有動態內存請求的大小都會經過一個過濾函數:goodMallocSize(在folly/Malloc.h中)處理,以獲取一個對jemalloc友好的值

goodMallocSize在不同的請求區間,將請求大小設置為64b / 256b / 4KB / 4MB對齊,以提高分配/回收效率,減少內存碎片。

二. 常見操作的優化

fbstring在實現時做了很多優化(如word-wise copy等),其中的細節不再一一敷述,感興趣的讀者建議去參考源碼,這里只列出重要的幾點:

1. 末尾'\0'的處理

fbstring的默認行為是“懶惰”添加'\0'(lazy append),即平時預留空間,只在調用data()或者c_str()時,才在結尾添加'\0',避免了每次修改字符串時的額外開銷(特別是push_back操作),因為這樣做是符合C++標準的。

(當然,fbstring也有相應的宏來關閉該行為)

2. realloc的處理

string很多時候需要realloc,為了優化realloc的效率,fbstring做了這樣的設定:

(1)如果使用jemalloc:使用jemalloc的非標準接口——rallocm

(2)沒有使用jemalloc:

當前內存的使用率小于50%(size * 2 < capacity),放棄使用realloc(因為realloc可能需要拷貝全部內存,而其中超過一半是無效內容),而是簡單采用free+malloc+copy的方式來重新分配內存,減少拷貝開銷。

當前內存的使用率大于50%,則使用realloc,寄希望realloc可以合并后面的內存(coalescing)以避免拷貝。

3. 優化string::find()

glibc的string::find()實現中只實現了簡單的逐字符查找比較功能,復雜度為O(M*N)。(C++標準并沒有規定string::find的復雜度要求)

find使用了簡化的Boyer-Moore算法,代碼中聲稱:

Casual tests indicate a 30x speed improvement over string::find()for successful searches and a 1.5x speed improvement for failed searches.

如果是簡單的短字符查詢,string::find()應該足夠高效。只有在長字符搜索的情況下,find的BM算法實現才能體現出優勢,或許這也是Facebook的常用場景吧。

結語:

順便提一下,fbstring(FBString.h)的作者為Andrei Alexandrescu(熟悉C++應該都聽說過),近距離欣賞大師的代碼實在是一種享受。

同時,Alexandre大叔以43歲的“高齡”,依然在Facebook寫著如此底層的程序。個中滋味,值得天朝所有浮躁的程序員(包括筆者在內)和“35歲論“者細細體味。

原文鏈接:http://www.cnblogs.com/promise6522/archive/2012/06/05/2535530.html

【編輯推薦】

  1. Facebook發布HTML 5應用中心
  2. HTML 5平臺對于Facebook未來至關重要
  3. Facebook版《憤怒的小鳥》為何選用Flash
  4. 揭秘Google與Facebook開發之道
  5. 揭秘Facebook是如何開發軟件的
責任編輯:彭凡 來源: 博客園
相關推薦

2012-06-05 09:12:02

FacebookFolly

2012-06-27 14:04:22

folly

2021-06-11 10:53:40

Folly組件開發

2010-01-19 10:29:41

C++類庫

2010-01-15 19:49:04

C++類庫

2010-01-15 19:49:04

C++類庫

2010-01-21 11:03:07

C++庫

2010-01-27 17:36:24

C++程序庫

2010-02-04 16:58:29

C++類庫

2019-09-18 09:05:26

微軟開源Windows

2010-02-03 16:04:34

C++標準類庫

2021-05-28 18:12:51

C++設計

2011-07-10 15:36:54

C++

2014-07-30 14:37:00

FacebookiOS開源庫

2015-09-06 11:07:52

C++設計模式單例模式

2011-07-15 00:47:13

C++多態

2011-05-18 17:33:15

CC++

2011-07-14 17:45:06

CC++

2010-01-21 13:33:44

C++基類

2010-01-19 18:04:02

C++標準程序庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧产日产国产精品国产 | 亚洲精品女人久久久 | 麻豆久久久久久久久久 | 国产一级一级 | 在线激情视频 | 成人一区二 | av在线一区二区三区 | 91精品国产色综合久久不卡蜜臀 | 国产精品久久9 | 国产男女猛烈无遮掩视频免费网站 | 精品国产欧美 | 免费av在线 | 亚洲一二三区av | 国产福利资源 | 亚洲视频网 | 精品欧美乱码久久久久久1区2区 | 国产在线观看一区二区三区 | 午夜精品一区二区三区在线观看 | 综合久久综合久久 | 日本久久黄色 | 亚洲精品色| 国产精品久久久久久中文字 | 精品成人一区 | 一区二区免费高清视频 | 久久看片| 日韩在线播放一区 | 一级毛片免费完整视频 | 一级毛片视频 | 波多野结衣一区二区 | 日本三级电影在线看 | 国产午夜精品一区二区三区在线观看 | 午夜欧美日韩 | 一区二区三区在线播放 | 成人区精品一区二区婷婷 | 欧美日韩中文国产一区发布 | 亚洲 欧美 综合 | 国产在线高清 | 国产精品久久久久久一区二区三区 | 午夜小视频在线观看 | 日本不卡一区二区 | 中文字幕一区二区三区日韩精品 |