【问题标题】:Why std::to_string() runs 16-times slower with MinGW than with VS2012为什么 std::to_string() 使用 MinGW 比使用 VS2012 慢 16 倍
【发布时间】:2013-07-28 22:18:21
【问题描述】:

当我对这个函数进行基准测试时,我很惊讶:

int f(int N = 999) {  
  int nMax = 0;

  for (int i = 1; i <= N; ++i)
    for (int j = i; j <= N; ++j) {
      string digits  = to_string(i*j);
      string rDigits = digits;

      reverse(rDigits.begin(), rDigits.end());

      if (digits == rDigits)
        nMax = max(i*j, nMax);
    }

  return nMax;
}

在 Windows 7 32 位和 64 位上使用 VS2012、VS2013(发布,/O2)和 MinGW 4.8.0、4.8.1 (-Ofast)。我注意到 MinGW 构建的版本比 VS 慢 13 倍。这是to_string()reverse() 实现的问题吗?还有其他原因吗?

我使用的代码在这里:https://github.com/pauljurczak/Benchmark-2/blob/master/benchmark.cpp

编辑

我将问题缩小到std::to_string() 函数,MinGW 比 VS 慢 16 倍。我用这个 sn-p 进行测试:

int f(int N = 100000) {  
  int len = 0;

  for (int i = 0; i <= N; ++i) 
    len += to_string(i).length();

  return len;
}

我在 Ubuntu 上用 g++ 4.7.3 编译,性能和 VS2012 差不多。

【问题讨论】:

  • 您正在运行基准测试,为什么不告诉我们哪个部分慢?
  • 使用 MinGW 的程序员是奇数。他们似乎从不想签入补丁并一直要求 SO 用户为他们做这件事。你不能同时拥有它。
  • 这个主题让我很感兴趣...例如,如果您尝试使用 MinGW 4.7.2 会发生什么?
  • 您在构造字符串时是否尝试过反转字符串,而不是作为缩小范围的第二步? string rDigits(digits.rbegin(), digits.rend()); 您的基准测试是否还包括任何类型的 I/O(例如 cout)?
  • @Antonio MinGW 4.7.2 编译此代码失败:未定义to_string()

标签: c++ visual-studio-2012 c++11 mingw benchmarking


【解决方案1】:

Visual Studio 可以反转if-条件:

if (digits != rDigits)
    continue;
else
    nMax = max(i*j, nMax);

但这只是猜测......

顺便说一句,我宁愿写:

string rDigits(digits.rbegin(), digits.rend());

你也可以看看:https://stackoverflow.com/a/17909430/1689664,它可能会给你一些优化算法的想法。

【讨论】:

  • 你甚至不需要reverse_copy,只需使用反向迭代器构造字符串string rDigits(digits.rbegin(), digits.rend());
  • 感谢您的优化想法,但我的问题是从 VS 迁移到 MinGW 时特定代码的性能会大幅下降。
  • @Blastfurnace string rDigits(digits.rbegin(), digits.rend()); 不会提高 MinGW 二进制文件的速度,会略微降低 VS 二进制文件的速度。
  • @PaulJurczak:您是否尝试反转if-条件? string rDigits(digits.rbegin(), digits.rend()); 之后 Visual Studio 二进制文件的速度是否相同?如果是,请与string rDigits = reverse_copy(digits.begin(), digits.end());比较速度...
  • 问题在于在 MinGW 中实现 std::to_string() - 请参阅我编辑的问题。
【解决方案2】:

检查您的 MINGW 构建使用的 C++ 运行时版本(使用依赖walker 或类似的东西)。 VS2012 支持 r 值,也许在您的情况下更重要的是小字符串优化。使用它可以消除来自 to_string 的任何内存分配。内存分配比查找最大值或反向需要更多的 CPU。

【讨论】:

    猜你喜欢
    • 2015-04-18
    • 2020-12-03
    • 2020-09-05
    • 1970-01-01
    • 2022-11-28
    • 2012-07-30
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多