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

我正在重写我的一个Android应用程序以利用NDK,每次打开一个1.5MB的文本文件(大约150k行)时,首先要做的事情之一就是把每一行放在一个数据中结构体。 当我使用Java的BufferedReader.readLine()执行此操作时,从SD卡读取文件大约需要2.5秒。 这是我用于此的代码:

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 } 

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

 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 ++很生疏,但是对于增加的读取时间没有任何合理的解释。 有一段时间我以为它可能是LOGDfunction,但我尝试完全取消它,读取时间根本没有多大帮助。 有没有人对这个问题有什么想法? 有没有更快的方法在C ++中逐行读取文件? 谢谢。

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

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

我没有测试过这段代码,但您可以尝试一下,看看它是否有所作为。

流是否可能是无缓冲的,并且它正在为每个数据字节进行SD访问? 要提供缓冲区,请执行以下操作(根据您的需要resize)。

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

C ++不会为您缓冲流(编辑: 默认情况下不会这样,请参阅Dave Smith的解决方案)。 我会告诉你,你的代码在普通的盘片磁盘上会很慢。 我没有很多android,fwiw的经验。

我通常使用这样的东西:

 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 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; } } 

这在任何地方都没有生产,所以除了你在这里看到的测试之外没有任何保证;)