[摘录] gcc 中std::list 的size()成员函数

来源:互联网 发布:船舶专业英语翻译软件 编辑:程序博客网 时间:2024/05/22 15:37

编者话:[ 这几天写一个Linux下邮箱日志的统计程序,用C++写.所以在网上搜集资料,正好看到hdqqq的一篇文章,也是将统计的,就特地摘录下载了]

这几天在写一个linux下的统计程序,主要是将一个文本文件读取后,按行进行分类统计.用C++加 Stl实现,在windows平台下用vc编写,然后上传到linux机器上用gcc编译.在处理上,我用了一个list<string>作为读取行的缓冲,读了一定的行数后就进行处理.在读取文件的函数中是这样写的.

 

while (!infile.eof()) {
      memset(buf, 
0, sizeof(char)*2048);
      infile.getline(buf, 
2048);
      tt 
= buf;
      
if (tt.length()) {
        log_list.push_back(tt);
      }

      
//if the file is too big, so we do statistic per 5000 lines
      
if (log_list.size() >= 5000) {
        line_statistic(result, log_list);
        log_list.clear();
      }
}


一切ok, 但是这几天要处理的文件变地很大,有100多M,我没有多想,随便的把
      if (log_list.size() >= 5000) {
改成了
      if (log_list.size() >= 50000) {
想在50000行后再进行计算处理.不料想,在linux下运行效率居然出奇的慢.
原先统计5万行大概要20秒左右,现在居然要2分多.应该是list::size()这个函数出了问题.我以前看过vc中的list的实现,是用一个成员变量进行记数的,在size()中就直接返回这个值,应该不会有问题.接着我看了gcc使用的stl的list::size()的实现,它是用std::distance(begin(), end())来计算的.但是在std::distance的实现中,它按照iterator类型的不同,实现的方式也不同.而list的iterator,是属于双向iterator,而非随机iterator,因此,在std::distance()中使用了一个循环来计算值.也就是说在gcc的stl库中,每次调用list::size()函数,它都会从头到尾遍历一遍.再看看我的代码,循环里面每一步size()都要遍历一遍list,难怪会变得如此的慢.


没想到stl的不同实现还会有这种陷阱,一不留神就撞上了.

总之 gcc中list的size()是不能随便用的,list越大,size()函数花的时间越长.

 

编者话:[文章原始出处http://www.cppblog.com/hdqqq/archive/2008/12/12/38216.html]

原创粉丝点击