【问题标题】:How to multi-thread an ANTLR parser in java如何在 java 中对 ANTLR 解析器进行多线程处理
【发布时间】:2012-06-13 14:52:44
【问题描述】:

我的程序在读取文件然后用 antlr 语法解析它时被证明很慢。为了提高性能,我想多线程解析?

读取文件:

    LogParser pa = new LogParser();
    LogData logrow;
    String inputLine;
    int a=0;
    try {
        //feed line by line
        FileReader fr = new FileReader(jFileChooser1.getSelectedFile());
        BufferedReader reader = new BufferedReader(fr);
        while ((inputLine = reader.readLine()) != null)
        {
            try {
                a++;
                jProgressBar.setValue(a);
                pa.parse(inputLine);  //decode the line
            } catch ... catches errors and send to logger
            } finally {

                logrow=new LogData(pa,a);
                mLogTable.addRow(logrow);//store the decoded line
            }

        } 
        reader.close();
    } catch ... catches errors and send to logger

代码解析带有pa.parse(inputLine); 的行,它将输入行发送到ANTLRStringStream,然后是CharStream,然后被解析。 接下来logrow=new LogData(pa,a); 获取将存储在我的表中的解码值。

我的分析显示热点位于根据我的语法构建的词法分析器和解析器类中(即 LogGrammarLexer 和 LogGrammarParser)。 希望它足够清楚......

解析:

LogGrammarLexer lexer = new LogGrammarLexer(inStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
decoded = new LogGrammarParser(tokens);
try {
    failurePosition="";
    decoded.logLine();
} catch (RecognitionException e) {
    failurePosition=Integer.toString(e.charPositionInLine);
} catch (Exception e) {
  failurePosition="-3";
  throw e;
} finally {
    return decoded;//TODO: see if return is necessary as decoded is now a field in class
}

另外我一直在阅读,现在知道多线程文件 I/O 没用... 无论如何,我需要改进的是我的语法在构建类中对文件中每一行进行复杂解码/解析的性能。

所以我的问题是如何使它成为多线程的,

干杯

【问题讨论】:

  • 看起来您正在从日志文件中解析行,而 Antlr 似乎对于该任务来说有点矫枉过正。在尝试优化 Antlr 或使用多线程之前,我会考虑使用正则表达式甚至手动解析它。
  • @BART:就像我已经说过的“我的分析显示热点位于根据我的语法构建的词法分析器和解析器类中”,我想我不够清楚......在我的 ANTLR 生成的词法分析器和解析器类中显示例如 mToken()。
  • @ALEX:哇,这太令人惊讶了,为什么要矫枉过正?这是完美的,因为我需要将所有数据存储在 jTable 中。 TBH 我的正则表达式有点生疏,而且由于解码的复杂性,我今年永远不会得到我需要的东西;)我实际上用 ANTLR 获得了惊人的速度,但这只是我削减了很多行。
  • 矫枉过正,因为可能有更简单的解决方案也可以满足您的需求。如果你能写一个 Antlr 语法,我很确定你能写一个正则表达式。
  • 想展示你的语法相关部分吗?也许有一些简单的方法可以优化它。

标签: java multithreading parsing antlr filereader


【解决方案1】:

如果每个文件行是一个单独的可解析实体,那么您可以有多个线程,如下所示:

  • 一个线程(很可能是主线程)从文件中读取行并将结果存储在工作队列中
  • 一个线程池,每个线程将从前面提到的工作队列中提取一个文件行并解析数据
  • 线程之间共享的文件行队列必须同步

只有在多核 CPU 上运行时,才会看到性能提升。

此外,这仅在每个文件行是一个单独的可解析实体时才有效,如前所述。如果可解析实体的概念跨越多行,或者是整个文件,那么线程将无济于事。此外,如果文件中行的顺序很重要,那么多线程可能会导致问题,因为这些行可能会被乱序解析。

这是一个标准的生产者/消费者问题,这里有一些有用的链接:

【讨论】:

  • 是的,这看起来是对的,我一直在寻找一个例子,我正在使用 swing,所以我认为它可能需要是 SwingWorker ???但我想不出我需要的代码,你能帮忙吗?
  • @xchiltonx,我不太确定 SwingWorker,因为这是一个 GUI 概念,而您正在做的工作不是 GUI 任务。这是一个标准的生产者/消费者问题。我会寻找一些例子并更新答案。
【解决方案2】:

看起来您可以简单地将输入文件分成几个,然后将它们导入并行线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多