неэффективен (производительность почти как виртуальная функция), но когда я заменяю std :: view by x.index () , производительность так же лучше, как CRTP .
my -код:
Я нашел, что использует std :: variant +[code]std::visit[/code] неэффективен (производительность почти как виртуальная функция), но когда я заменяю std :: view by x.index () , производительность так же лучше, как CRTP . my -код: [code]#include #include #include #include #include
namespace variant_shapes { // 圆形实现 - 不使用虚函数 class Circle { private: double radius_; public: explicit Circle(double radius) : radius_(radius) {}
for (int i = 0; i < 1000; ++i) { if (i % 2 == 0) { shapes.emplace_back(variant_shapes::Circle(5.0)); } else { shapes.emplace_back(variant_shapes::Rectangle(4.0, 6.0)); } } auto visitor = [](auto &&arg) -> double { using T = std::decay_t;
if constexpr (std::is_same_v) { return arg.area(); } else if constexpr (std::is_same_v) { return arg.area(); }
};
for (auto _ : state) { double totalArea = 0.0; for (const auto& s : shapes) { totalArea += std::visit(visitor, s); } benchmark::DoNotOptimize(totalArea); } } BENCHMARK(BM_StaticDispatch);
for (int i = 0; i < 1000; ++i) { if (i % 2 == 0) { shapes.emplace_back(variant_shapes::Circle(5.0)); } else { shapes.emplace_back(variant_shapes::Rectangle(4.0, 6.0)); } } auto visitor = [](auto &&arg) -> double { using T = std::decay_t;
if constexpr (std::is_same_v) { return arg.area(); } else if constexpr (std::is_same_v) { return arg.area(); }
};
for (auto _ : state) { double totalArea = 0.0; for (const auto& s : shapes) { totalArea += s.index() == 0 ? get_area(std::get(s)) : get_area(std::get(s)); } benchmark::DoNotOptimize(totalArea); } } BENCHMARK(BM_StaticDispatch2); [/code] Ссылка на тест на производительность: Quick C ++ Benchmark.