0

在 Windows 上执行时,此测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <assert.h>

int main() {
    // The clock() function returns an approximation of processor time used by the program.
    // The  value  returned is the CPU time used so far as a clock_t;
    // to get the number of seconds used, divide by CLOCKS_PER_SEC.
    auto buf = new char[1048576]; // 1MB
    auto cache = new char[512 * 1024];

    // initialize the buffer
    for (int i = 0; i < 1048576; ++i)
        buf[i] = i;

    auto fp_reopen = freopen("data_freopen.bin", "wb", stdout);
    assert(fp_reopen != nullptr);
    setvbuf(fp_reopen, cache, _IOLBF, 512 * 1024);
    auto clock_begin = clock();
    for (int i = 0; i < 1000; ++i) {
        auto n = fwrite(buf, 1048576, 1, fp_reopen);
        assert(n == 1);
    }
    fflush(fp_reopen);
    auto clock_end = clock();

#ifdef _WIN32
    freopen("CONOUT$", "w", stdout);
#else
    freopen("/dev/tty", "w", stdout);
#endif

    printf("write with freopen clocks elapsed: %zu\n", clock_end - clock_begin);

    auto fp = fopen("data_fopen.bin", "wb");
    assert(fp != nullptr);
    setvbuf(fp, cache, _IOLBF, 512 * 1024);
    clock_begin = clock();
    for (int i = 0; i < 1000; ++i) {
        auto n = fwrite(buf, 1048576, 1, fp);
        assert(n == 1);
    }
    fflush(fp);
    clock_end = clock();
    fclose(fp);

    printf("write with fopen clocks elapsed: %zu\n", clock_end - clock_begin);
    delete[] buf;
    delete[] cache;
    getchar();
}

生成这些结果:

  • write with freopen clocks elapsed: 2767
  • write with fopen clocks elapsed: 8337

为什么?

4

1 回答 1

4

您的问题很有趣,但高度系统特定:

  • 在带有 gcc 和 Glibc 的 Linux 上,两次运行的时间都非常相似
  • 在 OS/X 上,使用 clang 和 Apple Libc,fopen时间似乎总是比freopen那些快一点。
  • 您正在 Windows 上运行您的测试,正如最后一次调用所getchar()建议的那样......不幸的是,我无法测试这个系统来尝试交叉检查您的观察结果。

微软可能在他们的运行时库中做了一些奇怪的事情,但更有可能你真的在对 2 个单独的 1GB 文件的创建进行基准测试。由于文件系统的状态、缓存或其他特定于操作系统的原因,第二个文件的创建时间可能比第一个文件长。您应该尝试通过在关闭每个文件后删除它来消除这种潜在的副作用,或者尝试以不同的顺序运行测试。

于 2017-09-19T21:18:53.480 回答