速度小测试

· · 个人记录

这是我用机房的电脑测试出来的数据。cpu 配置为 Intel i5-12500。编译器 GCC 14.1,mingw64。编译选项 -std=c++17 -O2。

  1. 做 1e10 次乘法约需 6.7 秒。平均一次需要 0.67 纳秒。
  2. 做 1e10 次加法约需 1.2 秒。平均一次需要 0.12 纳秒。
  3. 做 1e9 次 固定模数 取模约需 2 秒。平均一次需要 2 纳秒。
  4. 做 1e9 次 非固定模数 取模约需 4 秒。平均一次约需 4 纳秒。
  5. 做 1e9 次 非固定除数 的除法约需 3.4 秒,比取模稍快。
  6. 做 1e9 次 固定除数 的除法约需 1.2 秒,比取模稍快。注意: 这里的时间有两种,在除数是某些质数时运行时间在 1.8 秒左右。对于其他的一些数字,约需 1.2 秒。
  7. 做 1e10 次 每次移一位的 左移约需 1.1 秒。速度与加法相近。这提示我们不要把 x * 2 写成 x << 1,因为编译器会把它优化成 x + x,时间与位移相近。
  8. 做 1e10 次 每次移随机位的 左移约需 2 秒。这提示我们左移的时间消耗与移动的位数有关。
  9. 做 1e10 次与运算约需 2.5 秒。(这一项在我的测试中出现了波动,有时是 2.2 秒,有时是 2.5 秒,有时是 2.7 秒左右,取平均约是 2.5 秒)
  10. 或运算的速度比与运算稍快,做 1e10 次或运算约需 2.3 秒。
  11. 做 1e10 次异或约需 2.3 秒,与或运算相近。

注意: 以上测试的是 unsigned long long 类型的运算。

以下是我对递归及内存分配的测试,编译选项 -std=c++14 -O2 -Wl, --stack=1000000000,CPU 为 Intel i5-4590。

递归非常慢,1e7 次的递归约需 100ms。递归会消耗大量栈空间,1e7 层的栈空间消耗达到约 1G。

测试代码:

#include <bits/stdc++.h>

using namespace std;
unsigned long long ans = 19260817;
void f(int a) {
    ans = (ans << 1) ^ (ans << 7) ^ (ans << 19);
    if (a) {
        f(a >> 1);
        ans++;
        f(a >> 1);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    auto t = chrono::steady_clock::now();
    f(n);
    cout << (chrono::steady_clock::now() - t).count() << "\n";
    cout << ans;
    return 0;
}

内存分配的测试:

1e7 次 (new + delete) 约需 400ms。

#include <bits/stdc++.h>

using namespace std;
unsigned long long ans = 1;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    auto t = chrono::steady_clock::now();
    for (int _ = 1; _ <= n; ++_) {
        unsigned long long x = (unsigned long long) new int();
        ans = ans * _ + x;
        delete (int *) x;
    }
    cout << (chrono::steady_clock::now() - t).count() << "\n";
    cout << ans;
    return 0;
}