在我的项目中,我需要下载一个html(读入String时长约50K-100K,是的,非常胖),并使用正则表达式获取一些内容。然后将它们插入数据库。 表现非常糟糕,我想知道原因。
代码的过程就像那样(多线程):
Pattern p = Pattern.compile("<h.*</a></h.>",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(html);
boolean result = m.find();
while (result) {
//insert into database stuff
//update database stuff
}
字符串很长,但是如果我将它分成几部分,可能会错过一些匹配。这非常令人不安。
我添加了一些打印行,发现在插入数据库之后,在更新操作之前有一些延迟,但由于未连接到数据库的连接,我无法弄明白。
答案 0 :(得分:2)
尝试避免正则表达式,使用标准的HTML解析器,如JSoup,有很多。我希望它们可能更有效率,至少比Regex更高效。
如果使用正则表达式,请不要每次都编译正则表达式。可以为Pattern
设置私有静态。但这不是表现上的巨大收获,只是良好的做法。
对数据库使用连接池。如果可能的话,进行批量插入。
答案 1 :(得分:2)
停在那儿。
你正在犯下性能调整时可能出现的最严重的错误之一。
您假设性能问题是您认为它在代码中的位置。
你不知道这一点,并且在你有确凿的证据之前,你可以优化错误的东西 - 并且可能会使情况变得更糟。
首先,您需要确认问题是应用程序代码。由于这是一个多线程应用程序,它正在下载数据(通过网络)并插入数据库(通过网络),因此您首先需要排除与线程监视器/锁定和网络/ IO问题有关的问题。
即使使用分析器也为时过早。如果您现在进行了简介,那么您可能会错过任何内容。
1)如果您没有打开GC开关,请立即打开它们。生产Java应用程序应从不运行而不进行GC日志记录。
2)重新运行测试用例,运行vmstat 1(如果是Unix)或任务管理器(如果是Windows)。
3)更新您的问题,详细说明在测试运行期间CPU利用率是否达到100%,我们可以进行下一步。
答案 2 :(得分:1)
使用分析器,例如VisualVM。它会准确地向您显示占用时间的方法。
在您的情况下,可以肯定的是,您使用正则表达式的方法并不理想。
编辑:我不同意对于探查器来说太早了。您可以监视线程,看看它们是否在等待锁定。此外,探查器将显示内存统计信息和CPU利用率 - 因此您将知道它是应用程序。分析器是使用的完美工具。
答案 3 :(得分:1)
使用正则表达式从HTML中提取值总是一个错误。 HTML语法可能首先出现得非常复杂,而且即使是非常复杂的正则表达式,页面也很容易识别出来。
用于解析HTML的模式匹配总是一项繁琐的任务。因为在正则表达式中,长字符串被分为组和子组,然后每个组和子组匹配模式。也许这就是为什么你的表现是慢..
请改用HTML Parser。另请参阅What are the pros and cons of the leading Java HTML parsers?