当前位置: 首页 > news >正文

NET 10 的正则性能现在什么水平?我拿它和 Go、Python、C++、PCRE2 测了一轮

为什么不用原文数据?
原文最大的问题不是代码写得怎样,而是测试数据没有给。

正则性能很吃输入分布。比如:

每行有多长
命中比例是多少
TSLA 出现在行首还是行尾
不命中的行是不是有很多“差一点命中”的内容
引号和转义字符有多少
.*? 中间到底要跨多少字符
这些东西一变,结果就可能变。

所以我没有试图“复现原文结果”。原文数据不公开,就没法严肃复现。我这里做的是另一件事:用公开、确定性的规则合成一份数据,然后把所有代码放出来,让别人可以重新跑。

数据生成脚本在仓库里,规则很简单:

生成约 1GB 的文本文件
每行是一个 JSON string literal
JSON string 里面再放一个紧凑 JSON object
每 20 行放一条 TSLA,也就是大约 5% 命中
固定随机种子,确保别人生成出来的数据一致
实际这次生成的数据是:

bytes: 1,073,741,855
lines: 4,624,532
expected matches: 231,227
pattern: “TSLA.*?”
seed: 20260702
所有实现都先把文件读进内存,然后只统计内存中扫描匹配的时间。读取时间也记录了,但不参与排序。

测了哪些实现?
这次一共测了 10 个:

case 说明
MSVC std::regex Visual Studio 18 / MSVC STL
MinGW std::regex GCC 16.1.0 / libstdc++
PCRE2 vcpkg PCRE2 10.47
PCRE2 JIT 显式 pcre2_jit_match
Python re Python 3.12.4
Go regexp Go 1.26.2
.NET Regex 普通 Regex,构造一次复用
.NET Compiled RegexOptions.Compiled,构造一次复用
.NET GeneratedRegex source generator 生成的正则
.NET NonBacktracking RegexOptions.NonBacktracking
这里有个小点要说明:普通 new Regex(…) 不是每行都 new 一次,而是构造一次后复用。每行都 new 那属于测错误用法,不是正常业务热路径。

.NET 这边大概是这样:

private const string Pattern = “\“TSLA.*?\””;

private static readonly Regex PlainRegex =
new(Pattern, RegexOptions.CultureInvariant);

private static readonly Regex CompiledRegex =
new(Pattern, RegexOptions.CultureInvariant | RegexOptions.Compiled);

private static readonly Regex NonBacktrackingRegex =
new(Pattern, RegexOptions.CultureInvariant | RegexOptions.NonBacktracking);

[GeneratedRegex(Pattern, RegexOptions.CultureInvariant)]
private static partial Regex InfoLineRegex();
核心循环也没什么花活:

private static long MatchLines(string[] lines, Regex regex)
{
long matches = 0;
foreach (var line in lines)
{
if (regex.IsMatch(line))
{
matches++;
}
}
return matches;
}
C++ 的 PCRE2 JIT 也不是“编译了 JIT 然后还调用普通 match”这种模糊写法,而是明确调用 pcre2_jit_match。完整代码直接看 GitHub 就行,这里不贴一大坨了。

结果
每个 case:

warmup 1 次
正式跑 3 次
只统计扫描匹配时间
所有 case 匹配数都必须等于 231,227
结果如下,按平均耗时排序:

排名 实现 平均单轮扫描
1 .NET GeneratedRegex 125.566 ms
2 .NET Regex 170.996 ms
3 .NET RegexOptions.Compiled 171.583 ms
4 .NET RegexOptions.NonBacktracking 219.780 ms
5 Go regexp 303.017 ms
6 MSVC std::regex 448.698 ms
7 PCRE2 JIT 612.498 ms
8 Python re 894.424 ms
9 PCRE2 5,191.270 ms
10 MinGW/libstdc++ std::regex 26,272.900 ms
.NET GeneratedRegex 三轮分别是:

125.294 ms
125.734 ms
125.669 ms
这个波动很小,所以至少在这份数据上,不像是偶然抖出来的。

另外我一开始也跑过 1MB 的小数据,那个时候 .NET 没这么明显的优势。这个也正常,1MB 太小了,JIT、tiered compilation、缓存状态、计时噪声都能影响结果。到了 1GB 之后,差距就稳定多了。

有几个结果挺有意思
第一,.NET GeneratedRegex 真的很猛。

这个结果对我来说有点爽,但不是完全意外。现在的 .NET Regex 对这类模式优化得确实很激进,source generator 又能把一些工作提前到编译期。这个 pattern 本身也简单,本质上更接近“找一个固定前缀,然后扫到后面的引号”。

第二,RegexOptions.Compiled 这次没赢普通 Regex。

两者基本持平,普通 Regex 还略快一点点:

.NET Regex: 170.996 ms
.NET RegexOptions.Compiled: 171.583 ms
所以现在写 .NET,别再机械地觉得 Compiled 一定更快。很多时候你真正应该先考虑的是 [GeneratedRegex]。Compiled 不是不能用,而是别把它当成无脑性能开关。

第三,NonBacktracking 也不等于更快。

这次它是 219.780 ms,比普通 .NET Regex 慢一些。NonBacktracking 的重点是避免灾难性回溯、提供更稳的线性行为,不是承诺所有正则都更快。

第四,PCRE2 JIT 这次没有赢。

这和很多人的直觉可能不一样。PCRE2 JIT 很强,但不是每个 pattern、每份数据都会碾压。这个 case 里 .NET 的路径显然更适合。

这里我也特意检查了一下,免得变成“JIT 其实没开”的低级问题:PCRE2 用的是 8-bit API,pcre2_compile、pcre2_jit_compile、pcre2_match_data_create_from_pattern 都在计时循环外;JIT case 检查了 pcre2_jit_compile 的返回值,失败会直接报错;真正扫描时调用的是 pcre2_jit_match,不是普通的 pcre2_match。所有实现也都是逐行 IsMatch/search,不是某些实现扫全文件、某些实现逐行扫。

所以 PCRE2 JIT 输给 MSVC std::regex 这件事我也觉得值得多看一眼,但目前看不是因为测试代码把 JIT 写错了。更可能是这个 pattern 和这份数据刚好不在 PCRE2 JIT 最舒服的区间。

第五,MinGW/libstdc++ 的 std::regex 还是那个味。

1GB 单轮 26 秒多。这个结果非常突出,突出到我都检查了好几遍匹配数。最后所有实现匹配数一致,所以至少这个 case 下它确实很慢。

怎么复现?
仓库:

http://www.jsqmd.com/news/1229089/

相关文章:

  • Python 测试代码
  • TinyMCE富文本编辑器:为技术团队提供高效内容创作解决方案
  • 2026年人保承保钢制柱型散热器生产厂家挑选攻略:鑫祥春暖通等优质企业梳理 - 每天一杯纯牛奶
  • Spring Boot 3 HTTP客户端替代Feign的实践指南
  • GitHub Copilot SDK工具权限管理:如何控制工具执行权限的完整指南 [特殊字符]️
  • 炉石传说技术增强插件HsMod:从游戏痛点到技术解决方案的完整指南
  • 数学学习终极指南:如何利用awesome-math资源库快速掌握数学核心概念
  • 2026 年临沂膜结构搭建撬装柜施工弧形大棚搭建本地施工厂家 TOP5 实测测评 - LYL仔仔
  • Vaadin Flow性能监控与调优:识别和解决瓶颈的实用工具
  • 沐曦股份选择 Gitee 企业版:从代码开源到算力实践,构建国产 GPU 开发生态
  • 如何在Linux桌面环境中全面部署Cyberpunk Neon主题:从GTK到Wayland的完整指南
  • 如何快速定制专属桌面宠物:5步创意设计完全指南
  • 2026 年青岛膜结构搭建 钢结构厂房搭建本地施工商家 TOP5 实测测评 - LYL仔仔
  • 5大智能升级:重新定义鸣潮游戏体验
  • React Native应用鸿蒙适配实战指南
  • 时间序列算法3---大模型-(6类聚类方法及数据处理量)
  • Apache Fury架构深度解析:多语言序列化框架的技术选型指南
  • Supertonic终极指南:打造本地化多语言语音合成的完整技术生态
  • Debian与Ubuntu核心技术差异与适用场景解析
  • 杭州不同品类黄金回收差价解析:金条、首饰、老金、K 金价格区别 - 奢侈品回收评测
  • 如何用30分钟构建你的AI金融分析大脑:TradingAgents-CN实战指南
  • Adapt Intent Parser生产环境部署:容器化、监控与扩展的最佳实践
  • 如何用AI工具永久保存你的微信聊天记忆:从数据提取到年度报告完整指南
  • 2026企业服务实测:AI品牌可见力全栈方案选型指南
  • 3步掌握macOS菜单栏终极整理术:Ice工具完全指南
  • 热修复技术:iOS-Tech-Weekly中的JSPatch与动态化方案深度解析
  • XCB库与wmutils/core:X窗口操作的底层技术解析与实用指南
  • django外键字段会自动在数据库字段后面加上_id
  • 3步掌握SpringBlade:从单体到微服务的平滑迁移终极指南
  • 2026年新疆昆仑雪菊怎么选?5家实测对比以及避坑推荐 - 中国远见品牌企业资讯