用过C++的肯定都知道getline(cin, str)这个用法吧,用于将某行读入到一个字符串对象中。但是根据我的测试,这个方法有严重的效率问题。

正则表达式行匹配器,匹配一个23M文件。用getline的总运行时间是21秒,用直接文件读取方法只有7秒。getline方法在屏蔽对读入数据的正则匹配后还运行了9秒上下。这里有人可能弄不懂,即使读取不用时间,getline花费的时间加正则运算时间不应该是总时间吗?结论是不是的,因为多个接口上下调用需要时间,str对象得到指针需要时间。所以其中还有一些时间差。不过getline方法效率差是显而易见的。

原因在于istream的类型和行的长度。我们是从文件中读取的,一次获得一个字符的取得的。ifstream应该没有弱智到一次只ReadFile一个字节,估计是用了1-4K的缓冲簇。对于大型文件,这个缓冲簇应该越大效率越高。但是stream不会知道输入流的长度,所以——

而且即使知道了,50W个byte就是50W次call调用,花多少时间自己考虑吧。

还有一个是string类型的问题。getline istream一般都是用string作为接收对象的,因为string几乎可以无限制的接收。在STL的实现中,string是vector一样的连续块分配。当长度超出的时候,就必须重新分配,然后复制数据,删除原先块。因此STL中建议给string对象reserve一个块来提高效率。不过getline开始的时候会earse string对象,可能在这里面保留区域就被OOXX了——

所以在大规模数据处理中,还是手来吧。