Optimize activation factory using binary search to make it 5x+ faster - #1633
Yexuan Xiao (YexuanXiao) wants to merge 7 commits into
Conversation
71f7592 to
842a9d9
Compare
|
Jon Wiswall (@jonwis) Ryan Shepherd (@DefaultRyan) Can you take a look at this PR? |
|
There are some DLLs in Windows that link multiple static libraries together into a single main.cpp (not even the module.g.cpp, hand-authored) entrypoint that rely on this "I know that Maybe try splitting apart the two steps? I agree that "search a table of names" is likely better than "scan." So your writer produces an constexpr array of |
|
Jon Wiswall (@jonwis) My patch only affects module.g.cpp, so if the entry point is hand-written, there's nothing it can do. |
Currently, C++/WinRT uses reverse-order string comparison and checks strings one by one with if statements to find the appropriate make function, which can be very inefficient. I observed that the WinUI repository uses 219 runtime classes (the module.g.cpp from my local WinUI build), and searching through them sequentially is undoubtedly slow and inefficient. By switching to binary search, the speed can be improved by a factor of five or more.
I wrote a benchmark that simulates both the original lookup logic and the updated logic. https://github.com/YexuanXiao/winrt-activation-bench
Before optimization, a single lookup took 170 ns; after optimization, it takes 30 ns.
The patch generates two separate
constexprtables, one ofstring_views and one of function pointers. Once the type is found from thestring_viewtable, the make function is called from the same position in the function pointer table. There's a macro for generating the declarations and these two tables, avoiding having to write the function name twice (once for the function declaration and once for the table element). Since the tables are only used once, I didn't usestd::pair, which makes it possible to calllower_boundwithout writing a lambda, and allows it to be merged with otherlower_bound<string_view*>calls.