Open kelbon opened 2 years ago
Unfortunately, the problem is deeper than it looks like. Queries from this map are used to do PQ requests and the driver requires zero terminated strings at the moment.
In this ticket const char*
overloads should be added to the driver first, after that the proposed optimization would be possible.
I have tested many variations such as compile time flat maps with various implementations.
Surprising as it may seem, but I came to the conclusion that, firstly, the naive std::map of std::string_view's is not so slow(may be compiler handles this situation as special). And the second - nothing can be done faster than llvm-like string switch. So i propose to use StringSwitch here, it is very well optimized, even no strings in binary(they are in instructions cash!): godbolt link+%7B+%7D%0A%0A++StringSwitch+%26Case(StringLiteral+S,+T+Value)+%7B%0A++++if+(!!Result+%26%26+Str+%3D%3D+S)+%7B%0A++++++Result+%3D+std::move(Value)%3B%0A++++%7D%0A++++return+this%3B%0A++%7D%0A++R+Default(T+Value)+%7B%0A++++if+(Result)%0A++++++return+std::move(Result)%3B%0A++++return+Value%3B%0A++%7D%0A%7D%3B%0A%0A%0Aauto+search(const+std::string%26+s)+%7B%0A++++return+StringSwitch%3Cint%3E%7Bs%7D%0A++++.Case(%22abc%22,+4)%0A++++.Case(%22float%22,+16)%0A++++.Case(%22string%22,+-204)%0A++++.Default(-1)%3B%0A%7D'),l:'5',n:'0',o:main.cpp,t:'0')),header:(),k:61.332928620953545,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1500,deviceViewOpen:'1',filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-std%3Dc%2B%2B2a+-O3',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:2),l:'5',n:'0',o:'+x86-64+clang+15.0.0+(Editor+%232)',t:'0')),header:(),k:31.392418967056386,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+15.0.0',editorid:2,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+15.0.0+(Compiler+%231)',t:'0')),k:7.274652411990104,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4) (Possibly with some improvements like optional->pointer(if it dsn't break optimizations) and interface with deduction guides from C++17)
Oh, sorry, i forget it is map <T, strng> not <string, T> So just string->string_view will be helpfull... Or it can be array of arrays of string views... (But it can be inflexibly(possible bad bugs after enums modiying and tricky because kDeferrable is not 2 here)
enum Mode {
kReadWrite = 0,
kReadOnly = 1,
kDeferrable = 3 //!< Deferrable transaction is read only
};
Best way of course is to replace enums with tagged_enums (where type assotiated with value) and just make a visit (auto generated switch enum case)
https://github.com/userver-framework/userver/blob/e37c78fb0112e7befa08ef078c4de8f0fb7de607/postgresql/src/storages/postgres/options.cpp#L23
Why this global variables are not constexpr ? Seems like std::string_view may be used here without any problems.
What about unordred_map, do it constexpr may be tricky, but there are not many values and constexpr flat map can be easialy created with standard algorithms