GCC 在编译非平凡类型的大型 std::array 时非常慢

问题描述

我有这两个简单的类:

#include <type_traits>

struct trivial {
    int m;
};
 
struct non_trivial {
    non_trivial() {}
};

static_assert(std::is_trivial<trivial>::value,"");
static_assert(!std::is_trivial<non_trivial>::value,"");

并且我正在使用 std::array 作为类型来测量这个简单代码的编译时间与 non_trivial 大小相关:

#include <array>

void foo() {
    std::array<non_trivial,1000> v;
}

一切都很好:编译时间,由 Godbolt 测量,似乎在不断改变大小,并且在 clang 12、GCC 11 和 MSVC 19.28 之间非常相似。测试的所有编译器的时间约为 800 毫秒。

但是如果我将聚合初始化添加v

#include <array>

void foo() {
    std::array<non_trivial,1000> v{};
}

那么 GCC 的编译时间似乎比随着大小线性增长更快:

  • 1000:676 毫秒
  • 2000 年:877 毫秒
  • 4000:1228 毫秒
  • 8000:2083 毫秒
  • 16000:5544 毫秒
  • 32000:17862 毫秒

虽然 clang 和 MSVC 编译时间似乎对聚合初始化不敏感。

此外,如果我将 non_trivial 替换为 trivial 作为数组类型,则未检测到效果效果似乎与使用的优化级别无关。

根据this question,我的两种情况应该是等价的,因为非平凡类型的std::array认初始化应该在所有元素上调用认构造函数,这与空聚合完全相同初始化。

在我看来 GCC 中的一个错误,存在于至少支持 c++11 的每个版本中。您对此有什么建议吗?

您可能会找到我的测试 here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)