Я публикую альтернативный подход, который не является верным, но показывает хорошие результаты, как показано ниже.
Основная идея такая же с @NathanOliver.
Идея состоит в инициализации набора данных {"first", ..., "fourth"}
во время компиляции с помощью квалификатора static constexpr
, чтобы получить прирост производительности во время выполнения:
В C ++ 17 и более, std::string_view
доступен, и имеет constexpr
ctors.
Таким образом, для улучшения производительности естественно применять static constexpr std::array
из std::string_view
.
Кроме того, для такого небольшого набора данных ~ 10 наивный линейный поиск с локальностью кэша смежных массивов иногда превосходит другие алгоритмы.
Поэтому я намеренно использую std::find
здесь.
Это легко сделать с помощью оператора C ++ 17, если с инициализатором , следующим образом:
if(static constexpr
std::array<std::string_view, 4>
v = {"first", "second", "third", "fourth"};
std::find(v.cbegin(), v.cend(), s) != v.cend())
Это можно представить в виде следующего компактного и переносимого синтаксического макроса сахара:
#include <tuple>
#include <array>
#include <string_view>
#include <algorithm>
#define IF_CONTAINS(str, ...) \
if(static constexpr \
std::array< \
std::string_view, \
std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value> \
v = {__VA_ARGS__}; \
std::find(v.cbegin(), v.cend(), str) != v.cend())
Этот макрос IF_CONTAINS
отлично работает как оператор if следующим образом:
Live DEMO
std::string s = "first";
IF_CONTAINS(s, "first", "second", "third", "fourth") {
std::cout << s << " is found" << std::endl;
}
Тест производительности 1
Сначала мы проверим эффективность этого подхода с помощью набора данных выше {"first", "second", "third", "fourth"}
.
Тесты выполняются с использованием Quick C ++ Benchmark, gcc-8.2, C ++ 17 и O3 .
Результаты следующие:
const std::string s = "first";
( Live DEMO )
в 1,1 раза медленнее, чем наивная реализация.
![enter image description here](https://i.stack.imgur.com/ZUUb6.png)
const std::string s = "second";
( Live DEMO )
3,7 раза быстрее, чем наивная реализация.
![enter image description here](https://i.stack.imgur.com/yMRLa.png)
const std::string s = "third";
( Live DEMO )
1,9 раза быстрее, чем наивная реализация.
![enter image description here](https://i.stack.imgur.com/XCSbL.png)
const std::string s = "fourth";
( Live DEMO )
в 3,1 раза быстрее, чем наивная реализация.
![enter image description here](https://i.stack.imgur.com/R3XKe.png)
Тест производительности 2
Наконец, мы тестируем производительность с набором данных {"1", ...,"10"}
.
Тестовый код такой же, как и у @pawel_j.
Этот тест показывает в 2,7 раза более быстрый результат, чем наивная реализация:
Live DEMO
![enter image description here](https://i.stack.imgur.com/Gs1jr.png)