访问变体与访问单个元素的性能

我正在试验一种用于任意精度算术的算法,并希望使用std::array. 并且由于我std::vector用作长整数的动态存储,因此我决定使用std::variant<std::array, std::vector>此短整数优化。我不确定 std::visit 的性能,所以我使用 Google 基准测试了它。事实证明,它std::visit比正常直接访问容器内的元素要快。

std::visit在 MSVC 上作为 switch case 实现,除了std::variant由于标记联合而具有更大的内存占用之外,怎么可能std::variant更快?有人对此有解释吗?

测试代码:

#include <array>
#include <variant>
#include "benchmark/benchmark.h"

static void VecOf_VariantOf_Vec_Arr(benchmark::State& state) {
    using ST = std::array<uint8_t, 20>;
    std::vector<std::variant<std::vector<uint8_t>, ST>> vec;

    vec.reserve(1024 * 1024);
    for (auto i = 0u; i < 1024 * 1024; ++i)
        vec.emplace_back(std::in_place_type<ST>);

    for (auto idx = 0u; auto _ : state) {

        std::visit([idx]<typename T0>(T0& e)
        {
            if constexpr (std::same_as<T0, ST>)
                e.fill(static_cast<uint8_t>(idx));
        }, vec[idx]);

        idx += 1;
        idx %= vec.size();

        benchmark::DoNotOptimize(vec);
        benchmark::DoNotOptimize(idx);
        benchmark::ClobberMemory();
    }
}
BENCHMARK(VecOf_VariantOf_Vec_Arr);


static void VecOf_Arr(benchmark::State& state) {

    std::vector<std::array<uint8_t, 20>> vec;
    vec.reserve(1024 * 1024);
    for (auto i = 0u; i < 1024 * 1024; ++i)
        vec.emplace_back();

    for (auto idx = 0u; auto _ : state) {
        auto& e = vec[idx];
        e.fill(static_cast<uint8_t>(idx));
        idx += 1;
        idx %= vec.size();
        benchmark::DoNotOptimize(vec);
        benchmark::DoNotOptimize(idx);
        benchmark::ClobberMemory();
    }
}
BENCHMARK(VecOf_Arr);

MSVC 上的结果:

海湾合作委员会的结果:

在 Clang 上的结果:

这是基准

以上是访问变体与访问单个元素的性能的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>