André
André

Reputation: 121

Why is {fmt} slower than std::stringstream?

From what I read online the {fmt} library is supposed to be incredibly much faster than e.g. stringstreams.

However, I did some simple benchmarking (measuring system time, see code below) and it seems that {fmt} is always slower than e.g. stringstreams. Am I getting something wrong?

uint64_t start;
uint64_t stop;

long MAXCOUNT = 10000000;

std::srand(123);

int* numbers =  new int[MAXCOUNT];
for ( int i = 0; i < MAXCOUNT; i++) {
    numbers[i] = std::rand();
}

{
    std::string result;
    start = currentTimeInMillis();
    for ( int i = 0; i < MAXCOUNT; i++) {
        result += fmt::format("Number {} is great!", numbers[i]);
    }
    stop = currentTimeInMillis();
    fmt::print("timing fmt : {} ms   /   string length: {}\n", stop-start, result.size());
}


{
    std::string result;
    std::stringstream ss;
    start = currentTimeInMillis();
    for ( int i = 0; i < MAXCOUNT; i++) {
        ss << "Number " << numbers[i] << " is great!";
    }
    result = ss.str();
    stop = currentTimeInMillis();
    fmt::print("timing stds: {} ms   /   string length: {}\n", stop-start, result.size());
}

A typical result (optimization level O3 - less is even worse) of this code is:

timing fmt : 1414 ms   /   string length: 264823200
timing stds: 1287 ms   /   string length: 264823200

Upvotes: 1

Views: 5925

Answers (1)

One Lyner
One Lyner

Reputation: 2004

First, I don't get the same numbers on my machine, for me fmt is faster:

timing fmt : 1713 ms   /   string length: 264825935
timing stds: 2483 ms   /   string length: 264825935

Second, to get a fair comparison, replace

result += fmt::format("Number {} is great!", numbers[i]);

with

fmt::format_to(std::back_inserter(result), "Number {} is great!", numbers[i]);

This improves the timing to (on my machine again)

timing fmt : 1153 ms   /   string length: 264825935
timing stds: 2482 ms   /   string length: 264825935

Upvotes: 17

Related Questions