前言
前两篇文章 part1 和 part2 基本上理清了 IsSplitter()
运行缓慢的原因 —— 在函数内部使用了带 Compile
选项的正则表达式。
但是没想到在 IsSplitter()
内部使用不带 Compiled
选项的正则表达式,整个程序运行起来非常快,跟静态函数版本的运行速度不相上下。又有了如下疑问:
- 为什么使用不带
Compiled
选项实例化的Regex
速度会这么快? - 为什么把
Regex
变量从局部改成全局变量后运行速度有了极大提升?除了避免重复实例化,还有哪些提升? - 为什么
PerfView
收集到的采样数据,大部分发生在MatchCollections.Count
内部,极少发生在Regex
的构造函数内部?(使用带Compiled
选项的正则表达式的时候) Regex.IsMatch()
是如何使用缓存的?- 直接实例化的
Regex
对象会使用正则表达式引擎内部的缓存吗? - 正则表达式引擎内部根据什么缓存的?
- 什么时候会生成动态方法?生成的动态方法是在哪里调用的?
本文会继续使用 Perfview
抓取一些关键数据进行分析,有些疑问需要到 .NET
源码中寻找答案。在查看代码的过程中,发现有些逻辑单纯看源码不太容易理解,于是又调试跟踪了 .NET
中正则表达式相关源码。由于篇幅原因,本篇不会介绍如何下载 .NET
源码,如何调试 .NET
源码的方法。但是会单独写一篇简单的介绍文章 。