vertextao
vertextao

Reputation: 63

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?

Upvotes: 0

Views: 533

Answers (1)

chqrlie
chqrlie

Reputation: 145297

Your question is interesting, but highly system specific:

  • on Linux with gcc and the Glibc, I get very similar timings for both runs
  • on OS/X, with clang and the Apple Libc, the fopen timings seem consistently a little faster than the freopen ones.
  • you are running your test on Windows, as the final call to getchar() suggests... I unfortunately cannot test this system to try and cross check your observations.

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.

Upvotes: 4

Related Questions