繁体   English   中英

C++17 std::variant 比动态多态慢吗?

[英]C++17 std::variant is slower than dynamic polymorphism?

我正在关注这个博客,并试图将动态多态代码替换为使用std::variantstd::visit 但是我无法让std::variant + std::visit比虚拟结构实现更好地工作。 慢了大约 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

对于动态多态性,我有以下intfloat

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选项比动态多态性方法慢吗? 我期待的不是这样! 我的方法和/或基准有问题吗?

使用variant不构成“静态多态”。 它仍然是动态多态性,因为编译器不知道哪种类型实际上属于variant 因此,有问题的代码必须尝试找出variant在运行时存储的内容,并且必须相应地分派这些调用。

请注意,您链接到的文章没有将其称为“静态多态性”。 它强调它只是与虚函数不同的“运行时多态”形式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM