C# 使用常量加速解析器?虽然是抽象类

本文关键字:抽象类 常量 加速 | 更新日期: 2023-09-27 17:56:39

我有一系列解析器,它们为相关数据解析相同的基本文本类型,但它们来自不同的来源,因此它们有所不同。我每天解析数百万个文档,因此任何速度优化都会有所帮助。

这是一个简化的示例来显示基本问题。解析器的设置使得有一个实际解析器实现的基本抽象解析器:

abstract class BaseParser
{
     protected abstract string SomeRegex { get; }
     public string ParseSomethingCool(string text)
     {
         return Regex.Match(text, SomeRegex).Value;
     }
     ....
 }
 class Parser1: BaseParser
 {
     protected override string SomeRegex { get { return "^.*"; } } // example regex
     ...
 }
 class Parser2: BaseParser
 {
     protected override string SomeRegex { get { return "^[0-9]+"; } } // example regex
     ...
 }

所以我的问题是:

  • 如果我要在 get 常量中返回的东西,它会加快速度吗?
  • 从理论上讲,如果它不使用属性并且一切都是直截了当的常数,这会加快速度吗?
  • 我能看到什么样的速度增加?
  • 我只是抓着稻草吗?

C# 使用常量加速解析器?虽然是抽象类

我不认为将属性转换为常量会给你带来任何明显的性能提升。无论如何,Jit'ed 代码可能都有这些内联(因为你输入了常量)。

我认为最好的方法是首先分析您的代码,看看哪些部分具有最大的优化潜力。我对要看的事情的建议:

  1. 正则表达式 - 如您所知,有时,构造良好的正则表达式会阐明快速和极慢之间的区别。它实际上是一个个案基础,取决于使用的表达式和你输入的文本。
  2. 替代方案 - 我不确定您执行哪种匹配,但可能值得考虑其他方法,特别是如果您尝试匹配的内容不是那么复杂。然后对结果进行基准测试。
  3. 代码的其他部分 - 查看瓶颈发生的位置。它是在磁盘 IO 中还是在 CPU 中?看看更多的线程是否会有所帮助,或者可能会重新访问读取文件内容的函数。

无论你最终做什么,衡量它总是一个很大的帮助。确定有机会的领域,找到更快的方法,然后再次测量以验证它是否确实更快。

获取中的东西已经是恒定的。

我敢打赌抖动已经在优化属性访问器,因此通过重构它们,您可能不会看到太多的性能提升。

我认为您不会从这种优化中看到明显的速度改进。 不过,您最好的选择是尝试一下并对结果进行基准测试。

一个会有所作为的更改是,如果你没有它就可以逃脱,就不要使用正则表达式。 正则表达式是一个相当大且有用的锤子,但并非每个钉子都需要那么大的锤子。

从你展示的代码中不清楚为什么你需要一个抽象类和继承。
使用虚拟成员的速度较慢。此外,您的孩子课程不是密封的。

你为什么不做这样的事情:

public class Parser
{
    private Regex regex;
    public Parser(string someRegex)
    {
        regex = new Regex(someRegex, RegexOptions.Compiled);
    }
    public string ParseSomethingCool(string text)
    {
        return regex.Match(text).Value;
    }
}

或者像这样

public static class Parser
{
    public static string ParseSomethingCool(string text, string someRegex)
    {
        return Regex.Match(text, someRegex).Value;
    }
}

但是,我认为如果使用多线程,您将获得最大的性能提升。可能你已经这样做了。如果您不查看任务并行库