为什么c ++ 11正则表达式(libc ++实现)如此之慢?

 我叫33妹 发布于 2023-02-06 13:01

我比较了Linux C正则表达式库,

#include 
#include 
#include 

int main()
{
    const int count = 100000;

    regex_t exp;
    int rv = regcomp(&exp, R"_(([a-zA-Z][a-zA-Z0-9]*)://([^ /]+)(/[^ ]*)?)_", REG_EXTENDED);
    if (rv != 0) {
            std::cout << "regcomp failed with " << rv << std::endl;
    }

    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < count; i++)
    {
            regmatch_t match;
            const char *sz = "http://www.abc.com";

            if (regexec(&exp, sz, 1, &match, 0) == 0) {
    //              std::cout << sz << " matches characters " << match.rm_so << " - " << match.rm_eo << std::endl;
            } else {
    //              std::cout << sz << " does not match" << std::endl;
            }
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast(end - start);

    std::cout << elapsed.count() << std::endl;

    return 0;
}

结果在我的测试机器上大约是60-70毫秒.

然后我用了libc ++的库,

#include 
#include 
#include 


int main()
{
        const int count = 100000;

        std::regex rgx(R"_(([a-zA-Z][a-zA-Z0-9]*)://([^ /]+)(/[^ ]*)?)_", std::regex_constants::extended);
        auto start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < count; i++)
        {
                std::cmatch match;
                const char sz[] = "http://www.abc.com";

                if (regex_search(sz, match, rgx)) {
                } else {
                }
        }
        auto end = std::chrono::high_resolution_clock::now();
        auto elapsed = std::chrono::duration_cast(end - start);

        std::cout << "regex_search: " << elapsed.count() << std::endl;


        start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < count; i++)
        {
                const char sz[] = "http://www.abc.com";

                if (regex_match(sz, rgx)) {
                } else {
                }
        }
        end = std::chrono::high_resolution_clock::now();
        elapsed = std::chrono::duration_cast(end - start);

        std::cout << "regex_match: " << elapsed.count() << std::endl;

        return 0;
}

regex_search和regex_match的结果大约是2秒.这比C的regex.h库慢大约30倍.

我的比较有什么不对吗?C++的正则表达式库不适用于高性能案例吗?

我可以理解它很慢,因为在c ++的正则表达式库中还没有优化,但是慢30倍就是太多了.

谢谢.


大家好,

谢谢回答.

抱歉我的错误我也使用了[] C,但后来我改变了,忘了改变C++代码.

我做了两处改动,

    我将const char sz []移出了C&C++的循环.

    我用-O2编译它(之前我没有使用任何优化),C库的实现仍然是大约60毫秒,但是libc ++的正则表达式现在给出一个数字,regex_search为1秒,regex_match为150毫秒.

这仍然有点慢,但没有原始比较那么多.

2 个回答
  • 如果你看看http://llvm.org/svn/llvm-project/libcxx/trunk/include/regex,你会看到这个实现regex_match是分层的atop regex_search,并且所有重载都提取子表达式匹配位置,即使只是进入被抛弃的当地临时工. regex_search使用一个调用它们vector__state对象,.resize()因此也可能是向量 - 当子表达式匹配时不需要所有堆分配和不必要,但需要跟踪以支持\1等正则表达式的perl样式扩展:old regcomp/ regexecC函数没有提供那些扩展功能,从来没有必要做这项额外的工作.当然,如果clang实现检查了正则表达式在编译期间跟踪匹配的需要并调用更精简,更快的函数以便在可能的情况下进行匹配,那将是很好的,但我想他们只是从支持一般情况开始.

    2023-02-06 13:04 回答
  • 下面两行就不会做同样的事情!

    const char  sz1[] = "http://www.abc.com";
    const char* sz2   = "http://www.abc.com";
    

    这已经足以让它成为一个不公平的考验.

    2023-02-06 13:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有