Cost of enum-to-string: C++26 reflection vs. the old ways
181–189 of 189 posts
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#182Earlier quoted context omitted.
Then why isn't part of the stdlib? Why should everybody maintain their own version?
Just wait for C++32 :-D. After all, we only got `std::string::starts_with` in C++20 and C++23 finally gave us `std::string::contains`. It's a clown show, you just need to take it with humor.
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#183> The header is the cost. Not the reflection. The reflection algorithm is fast – asymptotically ~0.07 ms per enumerator, essentially the same as the hand-rolled switch in the X-macro version (~0.06 ms). What makes reflection look expensive is : just including it costs ~155 ms per TU over the baseline. So speaking of old ways, I'm not a C++ dev, but a while ago saw someone comment that they still organize their C++ pr…
I'll just point out that Lakos updated his work with a new edition in 2019:
Large-Scale C++ Volume I: Process and Architecture
and there's scattered evidence that Volume II might be published in Feb. 2027 [1]
Large-Scale C++ Volume II: Design and Implementation
[1]: https://www.amazon.co.uk/Large-Scale-Implementation-Addison-...
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#184Earlier quoted context omitted.
Running the code immediately after making changes is the first line of testing. To run a huge test suite full of tests that are completely unrelated to the current changes would be stupid, it's a huge waste of time and energy. Yes, seriously, have you ever written a project from scratch? A simple .c file with a thousand lines in it should easily build and start within 100ms. A compiler should be able to do basic pars…
Waiting 2 minutes for unit tests of the relevant module is not very long - using bazel helps to only run the relevant unit tests, not the full suite.
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#185But interestingly the code can be improved. The issue is that meta::info[1] is a pure compile time object so in the original code we need to statically unroll the loop of the vector that contains it so that we can splice it in in the loop body. But if we convert it to our own objects, then we can use a plain for loop.
template
constexpr static inline auto reflect_type = ^^T; // not really necessary
template
requires std::is_enum_v
constexpr std::string_view to_enum_string(T val)
{
struct my_string_view { const char * ptr; size_t sz = strlen(ptr); };
static constexpr auto meta = std::define_static_array(
std::meta::enumerators_of(reflect_type)
| std::ranges::views::transform(
[](auto e) {
return std::pair{my_string_view{define_static_string(std::meta::identifier_of(e))}, extract(e)};
}));;
for (auto [name, value] : meta)
{
if (val == value) { return name; }
}
return "";
}
This actually generate less code bloat as, if the array is large it will use a plain loop instead of always unrolling. Also the meta array can now be used for as lookup table for dense enums, while I don't think it is doable with the original version. Supposedly GCC should be able to convert a if chain into a switch statement, but it doesn't seem to trigger here [edit: scratch that: GCC does the switch conversion for the original version].define_static{_array,_string} still feel as unnecessary magic, but hopefully they are only transient and we will be able to use std::vectors directly. Also somehow GCC doesn't let me use std::string_view and I had to introduce an helper string type.
edit: I literally learned everything I know about static reflection in the last 24 hours. It is complicated, but not that complicated.
[1] Not sure why, I suspect they want to avoid being constrained by ABI.
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#186> The header is the cost. Not the reflection. The reflection algorithm is fast – asymptotically ~0.07 ms per enumerator, essentially the same as the hand-rolled switch in the X-macro version (~0.06 ms). What makes reflection look expensive is : just including it costs ~155 ms per TU over the baseline. So speaking of old ways, I'm not a C++ dev, but a while ago saw someone comment that they still organize their C++ pr…
>...from John Lakos' Large-scale C++ software design from 1997... I'll just point out that Lakos updated his work with a new edition in 2019: Large-Scale C++ Volume I: Process and Architecture and there's scattered evidence that Volume II might be published in Feb. 2027 [1] Large-Scale C++ Volume II: Design and Implementation [1]: https://www.amazon.co.uk/Large-Scale-Implementation-Addison-...
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#187> The header is the cost. Not the reflection. The reflection algorithm is fast – asymptotically ~0.07 ms per enumerator, essentially the same as the hand-rolled switch in the X-macro version (~0.06 ms). What makes reflection look expensive is : just including it costs ~155 ms per TU over the baseline. So speaking of old ways, I'm not a C++ dev, but a while ago saw someone comment that they still organize their C++ pr…
>...from John Lakos' Large-scale C++ software design from 1997... I'll just point out that Lakos updated his work with a new edition in 2019: Large-Scale C++ Volume I: Process and Architecture and there's scattered evidence that Volume II might be published in Feb. 2027 [1] Large-Scale C++ Volume II: Design and Implementation [1]: https://www.amazon.co.uk/Large-Scale-Implementation-Addison-...
Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#188Re: Cost of enum-to-string: C++26 reflection vs. the old ways
#189Man that aucks was looking forward to some kind of speed improvement. Using magic enum atm and I guess we'll continue to do so. C++ build times are hard pill to swallow when migrating from c. This is just another reason we'll probably stick to writing c as t the company where I work. It's like asking someone to give up instant compilation for cleaner easier to read apps? Also now that we have cleanup handlers in c (d…