Jak Google dostosowuje standardową bibliotekę C++ do swoich potrzeb
Wyobraź sobie pisanie kodu dla systemów przetwarzających miliardy żądań. Biblioteka standardowa C++ (STL) jest dobra, ale czasami jej uniwersalność staje się wąskim gardłem. Gdzieś brakuje wydajności tablicy mieszającej, gdzieś brakuje wygodnej obsługi dat, a niektóre funkcje z nowych standardów C++20 lub C++23 chciałbyś używać już teraz, bez czekania na aktualizacje kompilatora na wszystkich serwerach.
Dokładnie w ten sposób powstał Abseil. To nie jest zamiennik STL, lecz rozszerzenie, którego Google używa w swoich wewnętrznych projektach, takich jak Wyszukiwarka, Reklamy i Mapy. Programiści po prostu wzięli kod sprawdzony przez lata i udostępnili go jako otwarte oprogramowanie.
Co kryje się w tym szwajcarskim scyzoryku
Jeśli zajrzysz do repozytorium abseil-cpp, znajdziesz dziesiątki bibliotek. Ale skupię się na tych, które naprawdę zmieniają codzienną pracę programisty.
Swiss Tables: gdy std::unordered_map jest zbyt wolna
W Abseil znajdują się rodziny kontenerów absl::flat_hash_map i absl::flat_hash_set. Google nazywa je „Swiss tables". W przeciwieństwie do standardowego std::unordered_map, który używa list powiązanych do rozwiązywania kolizji, Abseil wykorzystuje otwarte adresowanie i instrukcje SIMD do wyszukiwania. W praktyce zapewnia to zauważalny wzrost szybkości i oszczędność pamięci dzięki lepszej lokalizacji w pamięci podręcznej.
Inteligentna praca ze ciągami znaków
Biblioteka strings to ratunek dla zmęczonych pisaniem powtarzalnego kodu do podstawowych zadań. Na przykład absl::StrCat i absl::StrAppend działają szybciej niż zwykłe operatory + lub std::stringstream, ponieważ wstępnie obliczają wymagany rozmiar bufora i unikają niepotrzebnych alokacji. A absl::StrSplit pozwala podzielić ciąg znaków jedną linią kodu z elastycznymi filtrami.
Obsługa błędów bez wyjątków
Wiele dużych projektów wyłącza wyjątki w C++ ze względu na narzut lub kwestie bezpieczeństwa. W Abseil znajdziesz do tego celu absl::Status i absl::StatusOr<T>. To eleganckie rozwiązanie do zwracania z funkcji albo wyniku, albo kodu błędu z opisem tekstowym. Jeśli kiedykolwiek pracowałeś z Go lub Rust, to podejście wyda ci się bardzo znajome i logiczne.
Synchronizacja i czas
Zamiast standardowego std::mutex oferują absl::Mutex. Jest zaprojektowany tak, aby był bardziej wydajny przy dużej rywalizacji wątków. A biblioteka time znacznie upraszcza pracę ze strefami czasowymi i interwałami w porównaniu z przeciążonym std::chrono.
Filozofia techniczna: Live at Head
Abseil ma jedną cechę, która może albo odstraszyć, albo przyciągnąć. Google promuje koncepcję „Live at Head". Oznacza to, że zalecają zawsze budować projekt z najnowszej wersji master.
Programiści starają się nie łamać API, ale jeśli konieczna jest poprawa biblioteki, zrobią to. Aby ułatwić życie użytkownikom, Abseil dostarcza narzędzia do automatycznego refaktoryzacji kodu do nowych wersji API. Dla tych, którzy nie są gotowi na takie przygody, dostępne są wydania LTS, ale główny nacisk kładziony jest na ciągły rozwój.
Projekt obsługuje budowanie za pomocą Bazel i CMake. Jeśli już używasz Bazel, integracja Abseil zajmie tylko kilka minut.
Dla kogo to jest
Zalecałbym bliżej przyjrzeć się Abseil w dwóch przypadkach.
Po pierwsze, jeśli piszesz backend o wysokim obciążeniu. Zastąpienie standardowych map absl::flat_hash_map czasami daje wzrost wydajności za darmo, bez przepisywania logiki.
Po drugie, jeśli utknąłeś na starym standardzie C++ (na przykład C++17), ale bardzo chcesz używać funkcji z C++20. Abseil często backportuje nowe możliwości języka, udostępniając je na starszych kompilatorach.
Abseil to nie tylko zbiór narzędzi, ale odzwierciedlenie tego, jak kod jest pisany w jednej z najbardziej zaawansowanych technologicznie firm na świecie. Biblioteka jest ogromna, czasami złożona, ale niesamowicie wysokiej jakości. Jeśli potrzebujesz czegoś więcej niż oferuje biblioteka standardowa lub walczysz o każdy procent wydajności, zdecydowanie jest to narzędzie warte posiadania w twoim arsenale.
Najlepszym sposobem na rozpoczęcie nauki jest oficjalny przewodnik, ponieważ README w repozytorium jest dość krótkie i służy bardziej jako mapa folderów projektu.
Powiązane projekty