C# 中的快速字符串解析

问题描述 投票:0回答:2

在 C# 中解析字符串最快的方法是什么?

目前我只是使用字符串索引(

string[index]
)并且代码运行合理,但我忍不住认为索引访问器所做的连续范围检查必须添加一些东西。

所以,我想知道我应该考虑哪些技术来增强它。 这些是我最初的想法/问题:

  1. 使用
    string.IndexOf()
    IndexOfAny()
    等方法来查找感兴趣的字符。 这些比通过
    string[index]
    手动扫描字符串更快吗?
  2. 使用正则表达式。 就我个人而言,我不喜欢正则表达式,因为我发现它们很难维护,但是这些可能比手动扫描字符串更快吗?
  3. 使用不安全的代码和指针。 这将消除索引范围检查,但我读到不安全的代码不会在不受信任的环境中运行。 这究竟意味着什么? 这是否意味着整个程序集不会加载/运行,或者只有标记为不安全的代码才会拒绝运行?该库可能会在多种环境中使用,因此能够回退到较慢但更兼容的模式会很好。
  4. 我还可以考虑什么?

NB:我应该说,我正在解析的字符串可能相当大(比如 30k),并且采用自定义格式,没有标准的 .NET 解析器。 另外,这段代码的性能并不是非常关键,所以这在一定程度上只是一个好奇的理论问题。

c# parsing
2个回答
2
投票

30k 并不是我认为的大。在兴奋之前,我先介绍一下。索引器应该能够很好地实现灵活性和安全性的最佳平衡。

例如,要创建一个 128k 字符串(以及相同大小的单独数组),用垃圾填充它(包括处理

Random
的时间)并通过索引器对所有字符代码点求和需要... 3ms :

        var watch = Stopwatch.StartNew();
        char[] chars = new char[128 * 1024];
        Random rand = new Random(); // fill with junk
        for (int i = 0; i < chars.Length; i++) chars[i] =
             (char) ((int) 'a' + rand.Next(26));

        int sum = 0;
        string s = new string(chars);
        int len = s.Length;
        for(int i = 0 ; i < len ; i++)
        {
            sum += (int) chars[i];
        }
        watch.Stop();
        Console.WriteLine(sum);
        Console.WriteLine(watch.ElapsedMilliseconds + "ms");
        Console.ReadLine();

对于实际上很大的文件,应使用阅读器方法 -

StreamReader


2
投票

“解析”是一个相当不精确的术语。既然您谈到了 30k,那么您似乎正在处理某种结构化字符串,可以通过使用解析器生成器工具创建解析器来覆盖该字符串。

Devin Cook 的 GOLD 解析系统是一个创建、维护和理解整个过程的好工具:http://goldparser.org/

这可以帮助您创建高效且正确的代码来满足许多文本解析需求。

至于你的观点:

  1. 通常对于比分割字符串更进一步的解析没有用。

  2. 如果没有递归或太复杂的规则,则更适合。

  3. 如果您还没有真正确定这是一个严重的问题,那么
  4. 基本上是不行的。 JIT 仅在需要时才负责进行范围检查,实际上对于简单循环(典型的

    for
    循环),这处理得很好。

© www.soinside.com 2019 - 2024. All rights reserved.