C++ Logo

sg16

Advanced search

Re: Why stdout is the default in std::print? (P2093)

From: Dimitrij Mijoski <dim.mj.p_at_[hidden]>
Date: Thu, 03 Feb 2022 23:20:29 +0100
Here are some more complete benchmarks.

// Filename: cout.cpp
#include <cstdio>
#include <iostream>
#include <benchmark/benchmark.h>

void bm_printf_with_number(benchmark::State& s) {
    while (s.KeepRunning())
        std::printf("The answer is %d.\n", 42);
}
BENCHMARK(bm_printf_with_number);


auto theanswerstr = "The answer is 42.\n"; // This disables optimization to puts().
void bm_printf_with_string(benchmark::State& s) {
    while (s.KeepRunning())
        std::printf(theanswerstr);
}

BENCHMARK(bm_printf_with_string);

void bm_fwrite(benchmark::State& s) {
    const char str[] = "The answer is 42.\n";
    while (s.KeepRunning())
        std::fwrite(str, sizeof(str)-1, 1, stdout);
}
BENCHMARK(bm_fwrite);

void bm_fwrite_2(benchmark::State& s) {
    const char str[] = "The answer is 42.\n";
    while (s.KeepRunning())
        std::fwrite(str, 1, sizeof(str)-1, stdout);
}
BENCHMARK(bm_fwrite_2);

void bm_fputs(benchmark::State& s) {
    const char str[] = "The answer is 42.\n";
    while (s.KeepRunning())
        std::fputs(str, stdout);
}
BENCHMARK(bm_fputs);

void bm_puts(benchmark::State& s) {
    const char str[] = "The answer is 42.";
    while (s.KeepRunning())
        std::puts(str);
}
BENCHMARK(bm_puts);

void bm_ostream_with_number_sync(benchmark::State& s) {
    std::ios::sync_with_stdio(true);
    while (s.KeepRunning())
        std::cout << "The answer is " << 42 << ".\n";
}
BENCHMARK(bm_ostream_with_number_sync);

void bm_ostream_with_string_sync(benchmark::State& s) {
    std::ios::sync_with_stdio(true);
    while (s.KeepRunning())
        std::cout << "The answer is 42.\n";
}
BENCHMARK(bm_ostream_with_string_sync);

void bm_ostream_write_sync(benchmark::State& s) {
    std::ios::sync_with_stdio(true);
    const char str[] = "The answer is 42.\n";
    while (s.KeepRunning())
        std::cout.write(str, sizeof(str) - 1);
}
BENCHMARK(bm_ostream_write_sync);


// sync_with_stdio(false) must execute last

void bm_ostream_with_number(benchmark::State& s) {
    std::ios::sync_with_stdio(false);
    while (s.KeepRunning())
        std::cout << "The answer is " << 42 << ".\n";
}
BENCHMARK(bm_ostream_with_number);

void bm_ostream_with_string(benchmark::State& s) {
    std::ios::sync_with_stdio(false);
    while (s.KeepRunning())
        std::cout << "The answer is 42.\n";
}
BENCHMARK(bm_ostream_with_string);

void bm_ostream_write(benchmark::State& s) {
    std::ios::sync_with_stdio(false);
    const char str[] = "The answer is 42.\n";
    while (s.KeepRunning())
        std::cout.write(str, sizeof(str) - 1);
}
BENCHMARK(bm_ostream_write);

BENCHMARK_MAIN();
// End file.

/*
Compile with:
g++ -O2 cout.cpp -lbenchmark

Run with:
./a.out --benchmark_out=result.txt --benchmark_out_format=console > /dev/null && cat result.txt
./a.out --benchmark_out=result.txt --benchmark_out_format=console && cat result.txt
./a.out --benchmark_out=result.txt --benchmark_out_format=console > temp.txt && cat result.txt && rm temp.txt
./a.out --benchmark_out=result.txt --benchmark_out_format=console | grep -v "^T" && cat result.txt
*/

Here are some results for the invocation with /dev/null

----------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------
bm_printf_with_number 49.9 ns 49.9 ns 13779769
bm_printf_with_string 27.0 ns 27.0 ns 25868806
bm_fwrite 16.8 ns 16.8 ns 39413720
bm_fwrite_2 16.1 ns 16.1 ns 43543293
bm_fputs 17.1 ns 17.1 ns 40754496
bm_puts 17.5 ns 17.5 ns 40199289
bm_ostream_with_number_sync 69.9 ns 69.9 ns 10108714
bm_ostream_with_string_sync 20.8 ns 20.8 ns 33015280
bm_ostream_write_sync 20.2 ns 20.2 ns 34644654
bm_ostream_with_number 40.9 ns 40.9 ns 17251191
bm_ostream_with_string 10.9 ns 10.9 ns 64553114
bm_ostream_write 10.2 ns 10.2 ns 67825592

>From what I see, iostreams unformatted IO is fast even with sync
enabled. The only slower thing is bm_ostream_with_number_sync but that
is formatted IO.

Received on 2022-02-03 22:20:33