python - 使用 c++ 检索一些文本列比 python 慢得多

标签 python c++ regex split

我想读取一些大文件内容并检查一些列,然后根据示例行的列值存储一些文件行:

7774777761 72288833         2015/03/20     23:59:37       26       26   38 
  99944524 09671017         2015/03/20     23:59:44       18        1    8

我是这样用 Python 做的:

import sys
if __name__=="__main__":
    if (len(sys.argv)<4):
        sys.stderr.write('Usage: trk finame fout  column value \n ')
        sys.exit(1)
    finame=open(sys.argv[1],'r')
    result=open(sys.argv[2],'w')
    nos=open("nos.txt",'w')
    col=int(sys.argv[3])
    val=sys.argv[4]
    for l in finame:
        llist=l.split()
        try:
            if llist[col]==val:
                result.write(l)
        except:
            nos.write(l)
    result.close()
    nos.close()

然后尝试使用正则表达式在 C++ 中执行此操作:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;

int main(int argc, char* argv[])
{
  ifstream fstr;
  ofstream ofstr;
  string istr,result;
  int col;
  string val;
  if(argc<5){
    cout<<"you must enter right arguments"<<endl;
    cout<<"colgrab inputfile outputfile desired_col desired_val"<<endl;
    cout<<"for example :"<<endl;
    cout<<"colgrab TrkTicket.txt INCOM_HWI.txt 6 1"<<endl;
  }else{
    fstr.open(argv[1]);
    ofstr.open(argv[2]);
    col=atoi(argv[3]);
    val=argv[4];
    if(!fstr)
    {
      cerr << "File could not be opened" << endl;
      exit( 1 );
    }

    if(!ofstr)
    {
      cerr << "File could not be opened" << endl;
      exit( 1 );
    }
  }

  while(getline(fstr,istr)){
    //  cout<<istr<<endl;
    try {
      regex re(R"XXX( *(\d+) +(\d+) +(\d+/\d+/\d+) +(\d+:\d+:\d+) +(\d+) +(\d+) +(\d+).)XXX");
      std::smatch match;
      //cout<<istr<<endl;
      if (regex_search(istr, match, re) && match.size() > 1) {
        result = match.str(col);

        if(val==result){
          ofstr<<istr<<endl;
        }
        //cout<<result<<endl;
      } else {
        //result = std::string("No match found");
        //cout<<result<<endl;

      }
    } catch (std::regex_error& e) {
      // Syntax error in the regular expression
      //cerr<<"Syntax error in the regular expression "<<endl;
    }
  }


  return 0;
}

我这样做的目的是提高速度。但让我感到惊讶的是,对于一个 270 Mb 的文件,Python 版本在不到 10 秒的时间内完成了这项工作,但 C++ 版本无法在 10 分钟内完成这项工作。

如何修复 C++ 版本以在更短的时间内完成这项工作?


Python 版本 python 3.2

C++ 版本 GCC G++ 4.9.1


编辑 1

我尝试了所有建议的方法,并且使用 MikeMB 方法它们几乎是均匀的:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;

int main(int argc, char* argv[])
{
    ifstream fstr;
    ofstream ofstr;
    string istr,result;
    int col;
    string val;
    if(argc<5){
        cout<<"you must enter right arguments"<<endl;
        cout<<"colgrab inputfile outputfile desired_col desired_val"<<endl;
        cout<<"for example :"<<endl;
        cout<<"colgrab TrkTicket.txt INCOM_HWI.txt 6 1"<<endl;
    }else{
    fstr.open(argv[1]);
    ofstr.open(argv[2]);
    col=atoi(argv[3]);
    val=argv[4];
    if(!fstr)
       {
          cerr << "File could not be opened" << endl;
          exit( 1 );
       }

    if(!ofstr)
       {
          cerr << "File could not be opened" << endl;
          exit( 1 );
       }
    }

while(getline(fstr,istr)){
        stringstream sstr(istr);
        int i = 0;
        while (sstr >> result) {
           if (i == col-1 && result == val) {
               ofstr << istr << "\n";
               break;
           }
           i++;
        }
 


    return 0;
}

有没有办法进一步提高性能?

最佳答案

编辑 1 的答案:

  • 添加std::ios::sync_with_stdio(false);作为 main() 的第一行 不错的速度提升。

  • 您不需要读取一行然后将其转换为 stringstream - 您可以直接从 fstr 读取值以避免复制。

  • 要在毫秒内获取数据,您可以使用索引数据格式,例如将数据导入 SQLite database ,索引列并使用数据库查询来提取它。

关于python - 使用 c++ 检索一些文本列比 python 慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29782203/

相关文章:

python - 通过 Python 使用 Spark 准备我的大数据

c++ - 为什么使用构造函数而不是函数?

c++ - 将未知大小的 std::array 传递给函数

c++ - std::multimap 和 std::vector 之间的交叉?

r - 将全角字符串转换为半角字符串

java - Hadoop 自定义 InputFileFormat 生成空结果

python - 超出语言工作线程重新启动运行时重试计数 :python. 关闭并主动回收 - Azure 函数应用程序

python - 在 Google 应用引擎中操作 DateTime 对象

python - 如何在 Python 中对装饰器进行分组

javascript - regExp 接受任何格式的所有特殊字符至少一个数字一个大写一个字母