0

I'd like to extend my instrumental Profiler in order to avoid it affect too much performances. Im my current implementation, I'm using a ProfilerHelper taking one string, which is put whereever you want in the profiling f(). The ctor is starting the measurement and the dector is closing it, logging the Delta in an unordered_map entry, which is key is the string.

Now, I'd like to turn all of that into a faster stuff.

First of all, I'd like to create a string LUT (Look Up Table) contaning the f()s names at compile time, and turn the unordered_map to a plain vector which is paired by the string function LUT.

Now the question is: I've managed to create a LUT but std::string_view, but I cannot find a way to extend it at compile time.

A first rought trial sounds like this:

template<unsigned N>
constexpr auto LUT() {
   std::array<std::string_view, N> Strs{};
   for (unsigned n = 0; n < N; n++) {
      Strs[n] = "";
   }

   return Strs;
};

constexpr std::array<std::string_view, 0> StringsLUT { LUT<0>() };

constexpr auto AddString(std::string_view const& Str)
{
   constexpr auto Size = StringsLUT.size();
   std::array<std::string_view, Size + 1> Copy{};
   for (auto i = 0; i < Size; ++i)
      Copy[i] = StringsLUT[i];
   Copy[Size] = Str;
   return Copy;
};

int main()
{
   constexpr auto Strs = AddString(__builtin_FUNCTION());

   //for (auto const Str : Strs)
      std::cout << Strs[0] << std::endl;
}

So my idea should be to recall the AddString whenever needed in my f()s to be profiled, extending this list at compile time.

But of course I should take the returned Copy and replace the StringsLUT everytime, to land to a final StringsLUT with all the f() names inside it.

Is there a way to do that at compile time?

Sorry, but I'm just entering the magic "new" world of constexpr applied to LUT right in these days.

Tx for your support in advance.

  • 1
    I don't believe you can build a compile-time data structure from pieces spanning multiple translation units. `sizeof(StringsLUT)` must produce *some* constant value in every translation unit. If it produces different values, that would imply ODR violation. To somehow return the same value, the compiler would have to magically know what's in other translation units when compiling this one. – Igor Tandetnik Nov 14 '22 at 16:21
  • 1
    There are [non-standard implementation-specific ways](https://stackoverflow.com/questions/24283277/merging-global-arrays-at-link-time-filling-a-global-array-from-multiple-compil) to set up data structures at link time. If non-portable code is OK, you could look at such techniques for your compiler. – Igor Tandetnik Nov 14 '22 at 16:23
  • Currently the real problem is not about extending something which is a constexpr, but producing incremental update on the LUT with new arrays out of the old ones. I can understand this is a bit not standard conforming, since constexpr are meant to be kept const, by definition. I faced the same problem trying doing a compile time counter, since the constexpr management is supposed to be stateless. Honestly, I can't understand why the standard is not admitting constexpr with state. There's a good non-standard example here: https://b.atch.se/posts/non-constant-constant-expressions/ – riccardoventrella Nov 15 '22 at 12:23

0 Answers0