clang++ fstreams 10X slower than g++
Asked Answered
F

1

8

Q: Is there a way to speed up clang++ STD Library fstreams? (And does anybody know why it is so much slower than g++?)

I am trying to process very large (many GBs) binary data files and was surprised to find the performance was so poor. At first, I thought it was something to do with my code. But I am seeing the same slow performance in a boiled down example.

I even tried allocating different size buffers via rdbuf()->pubsetbuf() but this didn't seem to have much effect.

Here is a simple input/output example:

#include <fstream>

int main() {
    std::ifstream is {"bigSourceFile"};
    std::ofstream os {"bigSourceFileCopy"};

    std::string line;
    while (std::getline (is, line) ) {
        os << line;
    }
}

Here is some code to generate a 1.3GB source file. Use this to generate the source file for the readWrite program:

#include <fstream>
#include <string>

std::string createTailStr () {
    std::string result {"__"};
    for (auto i (0); i< 58; ++i) {
        result += 'A'+i;
    }

    return result;
}

int main() {

    std::string tail {createTailStr()};

    std::ofstream os {"bigSourceFile"};

    constexpr auto Lines (20000000ul);
    for (auto i (0); i < Lines; ++i) {
        os << i << tail << '\n';
    }
}

On my machine (running OSX El Capitan and the latest Xcode): the example (the first code listing) takes aprox. 50 seconds to run compiling from the command line:

clang++ -std=c++11 -o readWrite readWrite.cpp

However, when compiling against g++ and its libstdc++, the program only takes about 5 seconds.

I even built the latest cut of llvm stdc++ from llvm.org and that build was even slower (aprox 90 seconds).

To sum up: clang++ : 50 seconds; g++ : 5 seconds

Fateful answered 27/7, 2016 at 22:51 Comment(17)
fstreams are not part of the STL which only refers to the algorithms, containers and iterators elements.Goose
Did you try using clang with libstdc++? clang++ -stdlib=libstdc++Receive
What compiler options are enabled by default? Particularly the optimization levels.Masked
on my mac (clang) with optimisations enabled, time taken: 14 secondsRoanne
FWIW, on my Mac with Xcode 7.3, the compilers g++, gcc, clang++ and clang all seem to map to the same clang compiler: Apple LLVM version 7.3.0 (clang-703.0.29), which is in InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin.Mairamaire
@Goose -- thanks for the correction. I replaced STL for Standard Library.Fateful
@Receive -- Not exactly. I had used: 'clang++ -std=gnu++11 -stdlib=libstdc++' to pick up the libstdc++. For this example, 'clang++ -std=c++11 -stdlib=libstdc++' does work, too. However, generally, I haven't had much success mixing libstdc++ without -std=gnu++11.Fateful
@M4c -- The times stated were with the default options. In my original code the optimizations were not helping more than a few percent. However, for this using -O3, has a bit more impact. The time dropped from 50 sec, to 16 sec.Fateful
@RichardHodges -- Yes, for this particular case -O3 is having a notable impact. I saw 16 seconds down from 50 seconds. However, in original code, it wasn't that significant. So I didn't think to try anything besides the default settings for this example.Fateful
@RudyVelthuis -- I am running Xcode 7.3.1 (clang-7.3.0.7030031). clang++ does point to clang. However, g++/gcc is based off of 4.2.1. The way, I typically compile for g++ is : 'clang++ -std=gnu++11 -stdlib=libstdc++' .Fateful
If you are processing binary data, what << and >> are doing in your code?Fleeta
@n.m.: Take a look at the second piece of source code. It tells you the lines that are written. It is ASCII text. I guess getline() could be a hint as well.Mairamaire
@Tal: what does "gcc --version" display? In my case the same string as clang, clang++ and g++, i.e. what I showed in my other comment.Mairamaire
@RudyVelthuis binary data doesn't have lines. Text has lines. If one processes binary data, it makes little sense to benchmark facilities designed for processing formatted text.Fleeta
@n.m. Exactly. So it is obviously text. And that is also why there are << and >> in the code.Mairamaire
@RudyVelthuis OP says "I am trying to process very large (many GBs) binary data files", and then it's suddenly text.Fleeta
Well yes, the code shows it is.Mairamaire
C
1

GCC's fstreams (and cout, cerr, cin) are heavily optimized to work closely with the stdio facilities in the C library. That's why you get good performance, despite the widely held belief that "iostreams are slow".

The implementation in libc++ appears to be fairly straightforward, just following what the standard says to do without optimizing for performance. There's probably not much you can do about that as it would take rewriting big chunks of the libc++ streams impl.

Carmagnole answered 5/3 at 12:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.