【发布时间】:2021-10-05 03:37:46
【问题描述】:
我正在关注this blog,并试图将动态多态代码替换为使用std::variant 和std::visit。但我无法让std::variant + std::visit 比虚拟结构 impl 工作得更好。它大约 慢了 1.3-1.5 倍! (GCC 10.3 -O3 C++17)
用例如下。假设我们正在比较两个表的第 i 行和第 j 行。表可能具有异构类型的列。假设我们可以访问列缓冲区。 我正在做的是测试,
def IndexEqual(Table:A, Table:B, int:i, int:j):
for c in range(A.num_cols):
if not A.column(c)[i] == B.column(c)[j]:
return False
return True
对于动态多态性,我有以下int 和float
struct Comp{
virtual bool comp(size_t i, size_t j) const = 0;
};
struct CompI: public Comp {
CompI(const int *data_1, const int *data_2) : data1(data_1), data2(data_2) {}
const int *data1, *data2;
bool comp(size_t i, size_t j) const override {
return data1[i] == data2[j];
}
};
struct CompF: public Comp {
CompF(const float *data_1, const float *data_2) : data1(data_1), data2(data_2) {}
const float *data1, *data2;
bool comp(size_t i, size_t j) const override {
return data1[i] == data2[j];
}
};
bool IndexEqual1(const std::vector<Comp *> &comps, size_t i, size_t j) {
for (auto &&a: comps) {
if (!a->comp(i, j)) {
return false;
}
}
return true;
}
这被转换为std::variant + std::visit,如下所示。
struct EqualToI {
EqualToI(const int *data_1, const int *data_2) : data1(data_1), data2(data_2) {}
const int *data1, *data2;
bool comp(size_t i, size_t j) const {
return data1[i] == data2[j];
}
};
struct EqualToF {
EqualToF(const float *data_1, const float *data_2) : data1(data_1), data2(data_2) {}
const float *data1, *data2;
bool comp(size_t i, size_t j) const {
return data1[i] == data2[j];
}
};
using var_type = typename std::variant<EqualToI, EqualToF>;
bool IndexEqual(const std::vector<var_type> &comps, size_t i, size_t j) {
for (auto &&a: comps) {
if (!std::visit([&](const auto &comp) {
return comp.comp(i, j);
}, a)) {
return false;
}
}
return true;
}
我在这里进行了基准测试 https://quick-bench.com/q/u-cBjg4hyQjOs6fKem9XSdW7LMs
谁能解释一下为什么这个std::variant + std::visit 选项比动态多态方法慢?我的预期不是这样!我的方法和/或基准有问题吗?
【问题讨论】:
-
您关注的那个博客不是在描述静态多态性。试试这个博客:mropert.github.io/2017/11/30/polymorphic_ducks
-
std::variant有两种实现方式,动态调度和魔术。
标签: c++ polymorphism c++17 std-variant static-polymorphism