c++performancestdoutfreopen

Why it is faster writing a file which is freopened with stdout?


When executed on Windows, this test code:

#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();
}

Generates these results:

Why?


Solution

  • Your question is interesting, but highly system specific:

    It is possible that Microsoft did something weird in their runtime library, but more likely you are really benchmarking the creation of 2 separate 1GB files. It is possible that the second file takes longer to create than the first one, due to the state of your file system, its cache or other OS specific causes. You should try and remove this potential side effect by removing each file after closing it, or try running the tests in a different order.