C++ ifstream.getline() 明显比 Java 的 BufferedReader.readLine() 慢吗?
C++ ifstream.getline() significantly slower than Java's 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
}
使用c++使用ifstream需要更长的时间…同样的文件大约需要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++相当生疏,但我想不出任何合乎逻辑的解释为什么读取时间增加了。有一段时间,我认为它可能是LOGD功能,但我试着把它全部去掉,读取时间并没有真正有多大帮助。有人知道是什么问题吗?在c++中,有没有更快的方法来逐行读取文件?谢谢。
一个想法是stdio
同步可能会减慢您的速度。这是可以关闭的。我不知道这是否能解释所有的差异,但你可以试试。此外,您没有正确使用eof()
。最后,我将使用getline()
std::ios::sync_with_stdio(false);
ifstream ifs("/sdcard/testfile.txt");
std::string line;
while (getline(ifs, line))
{
LOGD(line);
}
我还没有测试过这段代码,但是您可以尝试一下,看看它是否有区别。
是否有可能流是未缓冲的,并且它正在为每个字节的数据进行SD访问?要提供缓冲,请执行以下操作(根据您认为合适的大小)。
ifstream ifs;
char stream_buffer[4096];
ifs.rdbuf()->pubsetbuf(stream_buffer, sizeof(stream_buffer) );
ifs.open(argv[1]);
c++不会为你缓冲流(编辑:默认情况下它们不会,参见Dave Smith的解决方案)。我会告诉您,您的代码在普通的基于盘片的磁盘上运行很慢。我对android没有太多经验。
我通常这样写:
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;
}
}
这不是在任何地方的生产,所以不保证超出您在这里看到的测试;)