robot-ya-builder 96458ea3c7 External build system generator release 65 11 months ago
..
CMakeLists.darwin-arm64.txt ffff7a34e4 add darwin-arm64 CMakeLists 1 year ago
CMakeLists.darwin-x86_64.txt 33ed6077e6 Intermediate changes 1 year ago
CMakeLists.linux-aarch64.txt 9f448c9c67 Intermediate changes 1 year ago
CMakeLists.linux-x86_64.txt 33ed6077e6 Intermediate changes 1 year ago
CMakeLists.txt 96458ea3c7 External build system generator release 65 11 months ago
CMakeLists.windows-x86_64.txt 6324d075a5 Intermediate changes 1 year ago
README.md cc2baf0174 intermediate changes 2 years ago
dispatch_methods.cpp 8e7094c87f intermediate changes 2 years ago
dispatch_methods.h e5e7d3b69b [enum_parser] generate ToStringBuf specialization 2 years ago
enum_runtime.cpp 8e7094c87f intermediate changes 2 years ago
enum_runtime.h e5e7d3b69b [enum_parser] generate ToStringBuf specialization 2 years ago
ordered_pairs.cpp 8e7094c87f intermediate changes 2 years ago
ordered_pairs.h c04b663c7b intermediate changes 2 years ago
ya.make bf0f13dd39 add ymake export to ydb 1 year ago

README.md

Enum serialization runtime support library

{% note warning %}

This library should not be used or referred directly. Use GENERATE_ENUM_SERIALIZATION_WITH_HEADER and GENERATE_ENUM_SERIALIZATION macros instead.

{% endnote %}

Implementation details

Code bloat

Использование шаблонов вида TVector<EEnum>, std::array<EEnum> или TMap<EEnum, TStringBuf>, а также алгоритмов поверх них, приводит к значительному разбуханию коде. Так как компилятор для разных перечислений вынужден генерировать разные специализации, даже если они компилируются в идентичный машинный код. Можно во многом выиграть если хранить не массив из EEnum, а массив из std::underlying_type_t<EEnum> (или из TSelectEnumRepresentationType<EEnum>::TType). Ведь различных типов-перечислений намного больше, чем целочисленных типов, на которых они базируются (и тем более больше, чем различных TSelectEnumRepresentationType::TType, коих всего четыре). И когда компилятор встречает вызов std::lower_bound, то для двух массивов из двух перечислений enum A: int {} и enum B: int{} он создаст две специализации, а если использовать целочисленные типы — то только одну. Всё это позволяет вынести вызовы вроде std::lower_bound в универсальные и переиспользуемые функции, принимающие например (TArrayRef<const int> values, int enumValue) своими аргументами. За счёт этого код 1) быстрее компилируется, 2) результат получается более компактным, 3) как следствие, он меньше засоряет во время исполнения кеш инструкций процессора одинаковыми или очень похожими специализациями функций.

Преобразование между enum и int выносится в пользовательский код (в шаблонные inline функции), и производится только в момент непосредственного использования (первым действием в семействе функций ToString, последним действием в семуйстве функций FromString), где оптимизирующий компилятор обычно может заменить их на no-op или на простые операции со значениями в регистрах. А контейнеры вида TVector<EEnum> и TMap<EEnum, ...>, которые возвращаются из функций util/generic/serialized_enum.h, заменяются на специальные классы TArrayView и TMappedDictView. Они также поддерживают быстрое и преобразование из перечислений в целочисленные типы и обратно в момент использования, и не требуют создавать специализации для каждого из возможных типов-перечислений.