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++中有没有更快的方法逐行读取文件?谢谢。
一种想法是
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; } } |
这不是在任何地方生产的,所以除了您在这里看到的测试之外,没有任何担保;)