【问题标题】:Is using Pattern/Matcher more efficient than looping through a string and looking for characters?使用 Pattern/Matcher 是否比遍历字符串并查找字符更有效?
【发布时间】:2019-03-13 19:28:22
【问题描述】:

我正在开发一个项目,该项目将通过 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 };
                        }
                    }

                }

            }

        }

【问题讨论】:

  • 这取决于......
  • 对于复杂的模式,可能。对于非常简单的字符搜索,几乎可以肯定不是。

标签: java regex performance iteration


【解决方案1】:

在您的特定情况下可能不会。

您按顺序扫描 Java String 一次。这比构建Matcher 然后使用它来做同样的事情要快。 Matcher 也必须至少扫描一次String,它没有任何魔力。

无论如何,在进行与性能相关的优化之前,请始终使用 profiler(例如 VisualVM)。


一个潜在的更大的问题是首先使用正则表达式解析 Java。这样的解决方案不可避免地是脆弱的(例如,可以单行编写Java方法,可以有嵌套类、泛型等)。

周围有很多 Java parsers 可以以更强大的方式完成这项工作。

【讨论】:

  • 啊,我什至没有考虑这种情况。我将考虑改用 java 解析器,但出于好奇,java 解析器会更高效(在这种情况下效率不是很重要),还是如你所说,它只是提供更强大的解决方案?
  • 解析器可能会比一个简单的正则表达式慢一点,但你会得到很多的鲁棒性作为回报。个人资料是肯定的。
【解决方案2】:

几乎可以肯定,是的

为什么

1) 您已经在逐行执行正则表达式。所以正则表达式已经在扫描整个文件,只是一块一块地。

2) 请记住,字符串在 Java 中是不可变的,所以

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

每行创建一个新的字符串对象。还要考虑readline 不会加载到整个文件中,然后一次将其交给您一行。即使不添加正则表达式,您也可能会看到一次读取文件然后逐行解析文件的速度有所提高。

注意:读取整个文件可能不可行。如果是这样,请忽略上面。

【讨论】:

  • 问题不在于 C#。
  • 啊,我明白你的意思了。虽然我使用的是 Java 而不是 C#,但字符串是不可变的仍然是正确的,所以这仍然是很好的信息。
  • 抱歉 - Java 字符串也是不可变的
猜你喜欢
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 2020-12-28
  • 2020-10-28
相关资源
最近更新 更多