c++ - Python 解析标准输入比 C++ 快得多

标签 c++ stdout stdio

我有一个 python 函数,我希望将其转换为 C++ 以尝试获得额外的速度(因为它将用于解析 >100GB 的文件)。我对 C++ 非常缺乏经验,并且惊恐地发现我的 C++ 函数在我的基本翻译后运行得慢得多。非常感谢任何关于为什么会这样或我可以做些什么来改进我的 C++ 代码的指示。

脚本概述:该函数从另一个程序读取标准输入,检查每一行是否有任何子字符串匹配,并将每一行打印到标准输出

Python function:

def find_tagPy(conditions):
    # conditions e.g. ['TTAT', 'TAT'] etc   
    for line in stdin:
        # Check conditionss against this line
        l = line.split("\t")

        if l[0][0] == "@":
            stdout.write(line)
            continue

        FLAG = int(l[1])

        if 1 & FLAG:  # Read has a pair
            for bases in conditions:
                if bases in l[9]:
                    ADD_MATE = 1
                    stdout.write(line)
                    break  # stop looking

C++函数:

void find_tagCpp (vector<string> conditions) {
    cin.sync_with_stdio(false);
    cin.tie(NULL);

    string line;
    while (getline(cin, line)) {
        vector<string> l;
        boost::split(l, line, boost::is_any_of("\t"), boost::token_compress_on);

        if (l[0][0] == '@') {
            cout << line << "\n";
            continue;
        }

        int FLAG = stoi(l[1]);
        int pair_FLAG = 1;

        if (pair_FLAG & FLAG) {  // Read has a pair
            for (int i=0; i < conditions.size(); i++) {  // If bases in SEQ
                if (l[9].find(conditions[i]) != string::npos) {
                    cout << line << "\n";
                    break;  // Stop looking
                }
            }
        }
    }
}

stdin 行的一个例子是:

FCC2CCMACXX:4:1105:10758:14389# 81 chrM 1 32 10S90M = 16151 16062 CATCACGATGGATCACAGGTCTATCACCCTATTAACACTCACGGGAGCTTTCCATGCATTTGGTATTTTCGTCTGGGGGTGTGCACGCGATAGCATTG bbb^Wc bbbbccbbbcbccbba]WQG^bbcdcb_^_c_^`ccddeeeeeeffggggiiiihiiiiihihiiihihiiiihghhiihgfgfgeeeeeebbb NM:i:1 AS:i :85 XS:i:65 RG:Z:1_DB31

在我的机器上,python 函数需要 1.97 秒,C++ 函数需要 11.05 秒(文件大小约为 25 MB,但这包括使用上游和下游工具进行的处理)

编辑:

我在 boost::split 中发现了一个有点令人惊讶的瓶颈:

python :

for i in range(100000):
    l = line.split("\t")

C++:

for (int i=0; i < 100000; i++) {
    vector<string> l;
    boost::split(l, line, boost::is_any_of("\t"), boost::token_compress_on);
}

Python = 0.0325 秒

C++ = 1.245 秒

但是我的文件只有 156,980 行,所以这不是全部问题。

最佳答案

拆分将片段复制到新的字符串中。这很慢,您不需要它们。而是在行中搜索您想要的片段的开头 ( 10th ),然后从那里开始调用查找。

关于c++ - Python 解析标准输入比 C++ 快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31453642/

相关文章:

java - 在 Ubuntu 上使用 Java - 包冲突?

c++ - 当 min 和 max 为正时,Rand() 返回负数

python - 如何在Python中调用程序的 'catch' stdin、stdout、stderr?

linux - 如何捕获已将其重定向到/dev/null 的正在运行的进程的标准输出

c++ - 返回前后字母的程序

c++ - WinAPI 在销毁前一个窗口后创建另一个窗口

C++ 错误 : expected identifier before ‘int’

windows - 为什么写入标准输出时 WriteFile 会崩溃?

android - 使用 NDK 捕获标准输出/标准错误

sscanf可以用来匹配通配符吗?