alexv-smirnov bf0f13dd39 add ymake export to ydb | 1 год назад | |
---|---|---|
.. | ||
CMakeLists.darwin-x86_64.txt | 1 год назад | |
CMakeLists.linux-aarch64.txt | 1 год назад | |
CMakeLists.linux-x86_64.txt | 1 год назад | |
CMakeLists.txt | 1 год назад | |
CMakeLists.windows-x86_64.txt | 1 год назад | |
README.md | 2 лет назад | |
dispatch_methods.cpp | 2 лет назад | |
dispatch_methods.h | 2 лет назад | |
enum_runtime.cpp | 2 лет назад | |
enum_runtime.h | 2 лет назад | |
ordered_pairs.cpp | 2 лет назад | |
ordered_pairs.h | 2 лет назад | |
ya.make | 1 год назад |
{% note warning %}
This library should not be used or referred directly.
Use GENERATE_ENUM_SERIALIZATION_WITH_HEADER
and GENERATE_ENUM_SERIALIZATION
macros instead.
{% endnote %}
Использование шаблонов вида 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
. Они также поддерживают быстрое и преобразование из перечислений в целочисленные типы и обратно в момент использования, и не требуют создавать специализации для каждого из возможных типов-перечислений.