添加日志输出后,Java应用程序速度会上升

时间:2012-09-07 22:32:13

标签: java performance

我们偶然发现了一个相当奇怪的问题IMO。我们的客户一直在抱怨我们的应用程序从文件导入和处理数据的速度[filesize 1kB cca,在正常条件下导入文件所需的时间是4-10秒,具体取决于整体工作负载。是的,这很多] ......

所以我们开始研究它,但发生了一些非常意外的事情:在将调试日志输出插入代码的某些部分后[不影响逻辑],导入加速了很多:300ms-2200ms / file取决于整体工作量。

使用的语言:Java

我的电台上的JDK 6_34 [不知道我的同事使用的版本]

我经历了很多次代码。没什么不寻常的。即使它全部在一个线程中执行,该线程也没有竞争对手做同样的工作或访问相同的文件。

这种情况对任何人都很熟悉吗?

P.S。:我希望这个问题确实属于这里。如果没有,我真诚地道歉。

编辑:

对于日志记录,我们使用log4j。

操作系统:Windows XP /我的机器。一位同事拥有相同的,另一位使用Win7 /

CPU:E7500 @ 2.93 GHz

RAM:2 GB DDR2

另一台机器基本相同。第三个配置对我来说是未知的,因为它是新的而不是我的工作站。

在我的情况下,文件都是从本地硬盘加载/存储的。

最让我担心的是,我们使用的是一个我们没有来源的平台,因为我们已经支付了许可费,但没有支付来源>。<

5 个答案:

答案 0 :(得分:5)

我的理论是,添加日志记录正在改变应用程序的线程调度模式。

通常情况下,这无关紧要。但是,如果应用程序中的基础问题与线程调度有关,那么日志记录会改变观察到的行为就不足为奇了。

我建议您审核代码库的相关部分,以查找Thread.sleep(...)次调用,Thread.yield()调用,代码轮询的位置等。还要考虑这可能发生在第三方库代码中。

@ OldCurmudgeon的答案包括你应该寻找的两个简单版本。即使使用sleep(0)也是浪费,但优于sleep(N) N显着大于零。

答案 1 :(得分:4)

您是否能够在您正在使用的计算机上重现客户的原始问题(即,您是否能够提取文件并按照您的提及需要4-10秒)?

如果没有,那么有太多因素需要专门给予log4j信用。我和威尔夫在这一个。添加日志无法可靠地提高代码的速度......至少我无法想到这一点。

如果你能够重现这个问题,那么添加日志,然后,使用相同的硬件,相同的逻辑和相同的文件可以大大提高速度,那么你已经正式开始了我的想法。

答案 2 :(得分:4)

在这种情况下,我所做的是在应用程序的关键部分(比如5-10个阶段)设置跟踪时间,并查看哪个部分花费的时间最多。在您的情况下,您可以看到哪个阶段加速。我怀疑只有一个阶段会更快,在这种情况下你可以放置更多的时间并缩小到你看到最大差异的代码。

在过去,你看到延迟有奇怪的增加,这已经归结为网络调用,例如DNS查找。处理文件时,您是否正在访问外部应用程序/网络服务?

答案 3 :(得分:3)

添加日志记录会为您的逻辑添加同步点。也许你所看到的是这种(奇数)副作用。

答案 4 :(得分:2)

你正在寻找旋转循环。

在代码(或底层框架)的某处,您的代码类似于:

while (!ready()) {
  // Do next to nothing.
}

或者归结为那种东西。

基本上,循环旋转得如此之快,它所等待的资源没有足够的时间可用。您通常也会看到奇怪的高CPU使用率。

日志记录缓解了这种情况,因为它会减慢循环速度,从而使资源准备就绪。

您需要将其更改为:

while (!ready()) {
  Thread.currentThread().sleep(0);
}

或者,理想情况下,使用适当的阻止机制。