-1

假设我正在编写一个解析器,我需要检查 Scanner::NextToken 返回的当前标记(例如)是否是一小组值之一(比如 5-10 个项目;少一些或多一些)。

在这个小型开源项目 (https://github.com/gsscoder/exprengine) 中,在 Parser 类中,我声明了我使用 Array::Contains() 查询的各种静态数组(请参阅 Parser::Ensure() 方法)。

我猜我是否可以使用扫描器中用于检查令牌的相同技术来提高性能,这是一种使用 if 语句的辅助方法(如下所示):

private static bool IsLineTerminator(int c)
{
  return c == 0x0A || c == 0x0D || c == 0x2028 || c == 0x2029;
}

或者也许这也在扫描仪中,我应该使用解析器中使用的技术?

任何意见(动机良好)将不胜感激;只是不建议使用像 ANTLR 这样的工具生成解析器/扫描器——我想保留一个手写的实现。

问候,贾科莫

4

1 回答 1

4

本质上,这正是Array.Contains正在做的事情。您将使用稍微多一点Contains的调用堆栈,因为它不会被内联到那种程度,但是发生的事情的基本概念是相同的。您不太可能会看到显着的性能差异,但无论如何都要分析这两种方法并亲自看看。 知道哪种方法更快的最好方法就是尝试一下,而不是随便问陌生人。

对于可能更快的实际算法更改要考虑的另一种选择是使用 aHashSet而不是数组。仅对于 4 个值,速度差异可能很小,但基于散列的数据结构是专门为更快的搜索而设计的。(至少也值得测试)。switch语句也将实现为基于哈希的解决方案,因此您也可以考虑使用它。

于 2013-01-04T17:24:19.700 回答