Увеличение производительности antlr - PullRequest
0 голосов
/ 26 июня 2019

Я строю процесс, который должен будет анализировать ~ 150 миллионов запросов в день из баз данных Oracle. Я использую грамматику PlSql для antlr здесь: https://github.com/antlr/grammars-v4/blob/master/plsql/PlSqlParser.g4

Antlr генерирует Lexer с 20k строками и парсер с 100k строками.

Вот пример разбора очень простого оператора select

from antlr4 import *
from antlr4.tree.Tree import TerminalNode
from plsql import PlSqlLexer, PlSqlParserListener, PlSqlParser
import datetime


def handleTree(tree, lvl=0):
    for child in tree.getChildren():
        if isinstance(child, TerminalNode):
            print(lvl*'│ ' + '└─', child)
        else:
            handleTree(child, lvl+1)


class KeyPrinter(PlSqlParserListener.PlSqlParserListener):
    def enterSelect_statement(self, ctx):
        handleTree(ctx, 0)


def main():
    now = datetime.datetime.now()
    i_stream = InputStream(str.upper("""SELECT col1 FROM table1"""))

    lexer = PlSqlLexer.PlSqlLexer(i_stream)
    t_stream = CommonTokenStream(lexer)
    parser = PlSqlParser.PlSqlParser(t_stream)
    tree = parser.sql_script()

    printer = KeyPrinter()
    walker = ParseTreeWalker()
    walker.walk(printer, tree)

    print(datetime.datetime.now()-now)


if __name__ == '__main__':
    main()

выход:

│ │ │ └─ SELECT
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ COL1
│ │ │ │ └─ FROM
│ │ │ │ │ │ │ │ │ │ │ │ │ └─ TABLE1
0:00:36.104422

Для анализа этого простого запроса требуется 36 секунд. Какие есть варианты для повышения производительности? Другой язык лучше?

  • В конечном итоге это будет микросервис REST, развернутый в Openshift. Я могу бросить на него много аппаратного обеспечения по многим пакетам, но сумма, которая мне сейчас нужна, неосуществима.
...