C#中的快速字符串解析

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

目前我只是使用字符串索引( string[index] )并且代码运行合理,但我不禁想到索引访问器所做的连续范围检查必须添加一些内容。

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

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

注意:我应该说,我正在解析的字符串可能相当大(比如30k),而且是自定义格式,没有标准的.NET解析器。 此外,这段代码的表现并不是非常关键,所以这部分只是一个好奇心的理论问题。

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等。

“解析”是一个非常不精确的术语。 因为你说的是​​30k,所以你可能正在处理某种结构化的字符串,可以通过使用解析器生成器工具创建解析器来解决这个问题。

创建,维护和理解整个过程的一个很好的工具是Devin Cook的GOLD Parsing System: http : //www.devincook.com/goldparser/

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

至于你的观点:

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

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

  3. 如果你还没有真正认定这是一个严重的问题,那么基本上是不行的。 JIT可以仅在需要时负责范围检查,实际上对于简单的循环(典型的for循环),这可以很好地处理。