在C

时间:2016-05-07 23:57:20

标签: c string optimization pattern-matching

作为高性能计算课程的一部分,我试图尽可能加快C语言中的天真字符串搜索,我想知道是否有任何明显的事情可以做到我错过了我当前的迭代,或者是否有更好的方向进入。

一些限制是必须从左到右搜索模式,每个字符必须单独检查,并且需要基于for循环。

到目前为止,我减少了999模式所需的时间。然后在9,999,999的文本中接着是B,接着是从约18秒到约9秒的B,但我不确定它是否可以考虑到上述限制,请加快速度。

目前的代码是:

int match(char** text, int n, char** pattern, int m){
    int i, j, last = n-m;

    for(i = 0; i <= last; i++){
        for(j = 0; j < m; j++){
            if((*text)[i+j] != (*pattern)[j]){
                break;
            }
        }

        if(j == m){
            return i;
        }
    }
    return -1;
}

如果文本是要搜索的文本,则pattern是要搜索的模式,n是文本的长度,m是模式的长度。

编辑:这是天真的字符串搜索算法的实现。 https://en.wikipedia.org/wiki/String_searching_algorithm#Na.C3.AFve_string_search

编辑2:@RadLexus想法后的代码从char **更改为char *(快25%):

int match(char* text, int n, char* pattern, int m){
    int i, j, last = n-m;

    for(i = 0; i <= last; i++){
        for(j = 0; j < m; j++){
            if(text[i+j] != pattern[j]){
                break;
            }
        }

        if(j == m){
            return i;
        }
    }
    return -1;
}

2 个答案:

答案 0 :(得分:4)

我只是通过这样做获得了10倍的加速:

for (int i = 0; i <= last; i++) {
    if (memcmp(&text[i], pattern, m) == 0) {
        return i;
    }
}

现在你可能会抱怨这不再使用&#34;对于&#34;循环,因此不是一个解决方案。但memcmp使用循环,如果您愿意,可以将其实现提升到代码中。至于为什么它的速度要快得多,我们在这里得到了一个很好的答案:Why is memcmp so much faster than a for loop check?

答案 1 :(得分:-1)

要仅使用循环,删除数组索引以支持指针可能会提供另一种加速:

int match(char* text, int n, char* pattern, int m){
    char *ptext= text, *pend= text+n, *ptext2;
    char *ppat, *ppatend;

    if (n<m) return -1;

    for (; ptext<pend; ptext++) {
        ptext2= ptext; ppat= pattern; ppatend= ppat+m;
        for (; ppat<ppatend; ppat++, ptext2++) {
            if (*ptext2 != *ppat) {
                break;
            }
        }
        if (ppat==ppatend) {
            return (ptext-text);
        }
    }
    return -1;
}