如何将条件链转换为更快,更简单的代码?

eyb*_*erg 0 java performance parsing dictionary antlr

我有9种不同的语法.其中一个将被加载,具体取决于它正在解析的文件的第一行txt.

我正在考虑将词法分析器/解析器派生到sep中.类,然后在我得到匹配时立即实例化它们 - 不确定这是否会减慢我的速度但不会.我想一些基准测试是有序的.

真的,速度绝对是我的目标,但我知道这是丑陋的代码.

现在代码看起来像这样:

sin.mark(0)
site = findsite(txt)
sin.reset()

if ( site == "site1") {
   loadlexer1;
   loadparser1;
} else if (site == "site2") {
   loadlexer2;
   loadparser2;
}
.................
} else if (site == "site8") {
   loadparser8;
   loadparser8;
}

findsite(txt) {
  ...................
  if line.indexOf("site1-identifier") {
    site = site1;
  } else if(line.indexOf("site2-identifier") {
    site = site2;
  } else if(line.indexOf("site3-identifier") {
    site = site3;
  }
  .........................
  } else if(line.indexOf("site8-identifier") {
    site = site8;
  }
}
Run Code Online (Sandbox Code Playgroud)

一些澄清

1)是的,我真的有9个不同的语法,我用antlr构建,所以他们将拥有自己的词法分析器/解析器objs.

2)是的,截至目前我们正在比较字符串,并且显然将用某种整数映射替换.我也考虑过将网站标识符粘贴到一个正则表达式中,但是我不认为这会加快任何速度.

3)是的,这是伪代码所以我不会对这里的语义过于挑剔..

4)kdgregory注意到我无法创建词法分析器/解析器对的一个实例是正确的

我喜欢哈希的想法,让代码看起来更好看,但我不认为它会加速我的速度.

kdg*_*ory 7

标准方法是使用Map将键字符串连接到将处理它们的词法分析器:

Map<String,Lexer> lexerMap = new HashMap<String,Lexer>();
lexerMap.put("source1", new Lexer01());
lexerMap.put("source2", new Lexer02());
// and so on
Run Code Online (Sandbox Code Playgroud)

一旦你检索到标识要使用的词法分析器的字符串,你就可以从Map中检索它,如下所示:

String grammarId = // read it from a file, whatever
Lexer myLexer = lexerMap.get(grammarId);
Run Code Online (Sandbox Code Playgroud)

但是,您的示例代码有一些怪癖.首先,indexOf()调用表明您没有独立字符串,并且Map不会查看字符串内部.所以你需要有一些方法从你读到的任何字符串中提取实际的键.

其次,词法分析器和解析器通常保持状态,因此您将无法创建单个实例并重用它.这表明您需要创建一个工厂类,并将其存储在地图中(这是抽象工厂模式).

如果你希望有很多不同的词法分析器/解析器,那么使用地图驱动的方法是有意义的.对于一个小数字,if-else链可能是你最好的选择,正确封装(这是工厂方法模式).