关于android:C ++ ifstream.getline()明显慢于Java的BufferedReader.readLine()?

C++ ifstream.getline() significantly slower than Java's BufferedReader.readLine()?

我正在重写我的一个Android应用程序,以利用NDK,它每次必须做的第一件事就是打开一个1.5MB的文本文件(大约150K行),并将每一行放入数据结构中。当我使用Java的BuffReDeReald.RealLoad()进行此操作时,从SD卡读取文件需要2.5秒。这是我用来做这个的代码:

1
2
3
4
5
6
7
8
9
try {
    BufferedReader br = new BufferedReader(new FileReader("/sdcard/testfile.txt"));
    String thisLine;
    while ((thisLine = br.readLine()) != null) {
        Log.d(TAG, thisLine);
    }
} catch (IOException e) {
    //Log error
}

使用IfSt流使用C++需要更长的时间…对于同一个文件大约需要3分钟。下面是我在C++中使用的代码:

1
2
3
4
5
6
7
8
9
char buffer[256];
ifstream ifs;
ifs.open("/sdcard/testfile.txt", ifstream::in);
if (ifs.is_open()) {
    while (!ifs.eof()) {
        ifs.getline (buffer,100);
        LOGD(buffer);
    }
}

我对C++很生疏,但是不能为增加的读取时间想到任何逻辑解释。有一段时间,我认为它可能是logd函数,但我尝试把它全部去掉,而阅读时间并没有真正起到什么作用。有人对这个问题有什么看法吗?在C++中有没有更快的方法逐行读取文件?谢谢。


一种想法是stdio同步可能会减慢您的速度。可以关闭。我不知道这是否能解释所有的区别,但你可以试试。另外,您没有正确使用eof()。最后,我将使用getline()的std::string版本。

1
2
3
4
5
6
7
std::ios::sync_with_stdio(false);
ifstream ifs("/sdcard/testfile.txt");
std::string line;
while (getline(ifs, line))
{
    LOGD(line);
}

我还没有测试过这个代码,但是你可以试试看它是否有什么不同。


流是否可能没有缓冲,并且它正在为每个数据字节执行sd访问?要提供缓冲区,请执行以下操作(根据需要调整大小)。

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


C++不为您缓冲流(编辑:默认情况下,不会看到戴夫·史密斯的解决方案)。我会告诉您,您的代码在普通的基于盘片的磁盘上会很慢。我对安卓系统没有太多经验。

我通常用这样的东西:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct buffered_reader {
    buffered_reader(std::istream &data_) : data(data_), done(false) {}
    bool next(std::string &line) {
        if (!lines.size()) {
            if (done)
                return false;
            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();
        return true;
    }
    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;
    }
}

这不是在任何地方生产的,所以除了您在这里看到的测试之外,没有任何担保;)