Является ли использование Pattern / Matcher более эффективным, чем циклическое прохождение строки и поиск символов? - PullRequest
1 голос
/ 13 марта 2019

Я работаю над проектом, который просматривает java-файл для конкретного метода и выводит строки, которые этот метод занимает в файле.Я уже использую Pattern и Matcher, чтобы найти метод, но затем я перебираю символы в строке, чтобы найти соответствующие фигурные скобки.

Мой вопрос: будет ли эффективнее использовать другой Pattern / Matcher для поиска пар фигурных скобок?

Вот метод, который находит диапазон строк для метода, если это помогает:

        String line;
        int currentLineNumber = 0;

        int methodStart = 0;
        int methodEnd = 0;

        int braceCount = 0;

        Matcher matcher;

        while ((line = lineReader.readLine()) != null) { // Must set line's value here because readLine() increments line number

            currentLineNumber = lineReader.getLineNumber();
            matcher = p.matcher(line); // initialize matcher with Pattern

            if (matcher.find()) { // if the line has a regex hit, store the line number as currentLine
                methodStart = currentLineNumber;
            }

            if (currentLineNumber >= methodStart && methodStart != 0) { // make sure that we've found the method
                for (int i = 0; i < line.length(); i++) { // iterates through characters in the line
                    /*
                     * Start with a braceCount of 0. When you find a starting brace, increment.
                     * When you find an ending brace, decrement. When braceCount reaches 0 again,
                     * you will know that you have reached the end of the method.
                     * 
                     * Could possibly reduce complexity/increase efficiency by using set of patterns/matchers
                     * to find braces. 
                     */
                    if (line.charAt(i) == '{') 
                        braceCount++;

                    if (line.charAt(i) == '}') {
                        braceCount--;
                        if (braceCount == 0) {
                            methodEnd = currentLineNumber;
                            return new int[] { methodStart, methodEnd };
                        }
                    }

                }

            }

        }

Ответы [ 2 ]

3 голосов
/ 14 марта 2019

В вашем конкретном случае, вероятно, нет.

Вы сканируете Java String последовательно один раз.Это быстрее, чем построить Matcher и затем использовать его, чтобы сделать то же самое.Matcher придется сканировать String хотя бы один раз, в нем тоже нет магии.

В любом случае всегда используйте профилировщик (например, VisualVM ), прежде чем углубляться в оптимизацию, связанную с производительностью.


Потенциально гораздо более серьезная проблема - это синтаксический анализ Java с помощью регулярных выражений.Такое решение неизбежно хрупко (например, можно написать метод Java в одну строку, могут быть вложенные классы, обобщенные типы и т. Д.).

Существует множество парсеров Java , которые могут выполнять работу гораздо более надежно.

1 голос
/ 13 марта 2019

Почти наверняка, да

Почему

1) Вы уже выполняете регулярное выражение в строке. Таким образом, регулярное выражение уже сканирует весь файл, просто по частям.

2) Помните, что строки являются неизменяемыми в Java, поэтому

while ((line = lineReader.readLine()) != null)

создает новый строковый объект для каждой строки. Также учтите, что readline не загружает весь файл, а затем передайте его вам по очереди. Вы, вероятно, заметите некоторое улучшение скорости чтения файла за один раз и последующего его анализа построчно, даже без добавления регулярного выражения.

ПРИМЕЧАНИЕ. Чтение всего файла может быть невозможным. Если это так, игнорируйте выше.

...