Skip to content Skip to sidebar Skip to footer

C++ Ifstream.getline() Significantly Slower Than Java's Bufferedreader.readline()?

I'm in the process of rewriting one of my Android applications to take advantage of the NDK and one of the first things it has to do every time is open a 1.5MB text file (approxima

Solution 1:

One thought is the stdio synchronization might be slowing you down. That can be turned off. I don't know if that would account for all of the difference, but you could try. Also, you're not using eof() correctly. Finally, I'd use the std::string version of getline()

std::ios::sync_with_stdio(false);
ifstream ifs("/sdcard/testfile.txt");
std::string line;
while (getline(ifs, line))
{
    LOGD(line);
}

I haven't tested this code, but you can try it and see if it makes a difference.

Solution 2:

Is it possible that the stream is unbuffered, and it's doing an SD access for each byte of data? To provide a buffer, do the following (size as you feel appropriate).

ifstream ifs;
char stream_buffer[4096];
ifs.rdbuf()->pubsetbuf(stream_buffer, sizeof(stream_buffer) );
ifs.open(argv[1]);

Solution 3:

C++ does not buffer streams for you (edit: they won't by default, see Dave Smith's solution). I will tell you that your code will be slow on a normal platter based disk. I don't have a lot of experience with android, fwiw.

I generally use something like this:

structbuffered_reader {
    buffered_reader(std::istream &data_) : data(data_), done(false) {}
    boolnext(std::string &line){
        if (!lines.size()) {
            if (done)
                returnfalse;
            std::string line;
            for (size_t i = 0; i < 500; i++) {
                std::getline(data, line);
                if (data.eof()) {
                    done = true;
                    break;
                }
                lines.push_back(line);
            }
        }
        line = lines.front();
        lines.pop_front();
        returntrue;
    }
    std::istream &data;
    bool done;

    std::deque<std::string> lines;
};

TEST(blah) {
    std::stringstream ss;
    ss << "a" << std::endl;
    ss << "a" << std::endl;
    ss << "a" << std::endl;
    ss << "a" << std::endl;

    buffered_reader reader(ss);
    std::string line;
    while(reader.next(line)) {
        std::cout << line << std::endl;
    }
}

This isn't in production anywhere, so no warranties beyond the testing you see here ;)

Post a Comment for "C++ Ifstream.getline() Significantly Slower Than Java's Bufferedreader.readline()?"