log4net比System.Diagnostics.Trace慢很多吗?

18

我正在研究使用log4net和System.Diagnostics.Trace进行日志记录之间的差异,并且对我观察到的性能差异很感兴趣。

我创建了一个测试应用程序,以比较两种记录方法在几个场景下的性能,并发现log4net比Trace类慢得多。例如,在没有字符串格式化的情况下记录1,000条消息时,log4net在1,000次试验中的平均执行时间为9.00毫秒。 Trace的平均执行时间为1.13毫秒。我的许多测试用例中,log4net执行时间的方差相对较大;离群值的周期性长时间执行似乎暗示GC干扰。通过CLR Profiler调查发现有大量生成的log4net.Core.LoggingEvent对象的集合(公平地说,Trace也会生成大量的Char[]对象,但它不显示log4net那么大的方差)。

我要记住的一件事是,即使log4net大约比Trace慢9倍,但是在1,000次迭代中的差异是8毫秒;这并不是显著的性能问题。尽管如此,我的一些预期使用情况可能会调用数十万次记录方法,而这些数字是从我的快速机器上获得的。在更符合我们用户配置的较慢的机器上,差异为170毫秒到11毫秒,这有点令人担忧。

log4net的性能是否典型,或者是否存在一些易错点可以显著提高log4net的性能?

注意:我知道字符串格式化会改变执行时间;我试图进行苹果与苹果的比较,并且我有没有格式化的测试用例和有格式化的测试用例;无论使用与否,log4net都保持着成比例的缓慢。

目前情况如下:

  • Robert Gould给出了最好的答案,我只是好奇是否log4net的性能比Trace类慢很多是常见的情况。
  • Alex Shnayder的回答提供了有趣的信息,但不属于问题的范畴。引入此日志记录的目的之一是为了帮助调试生产系统中的逻辑和性能问题;我们的客户将我们的产品放在许多奇特的场景中,这些场景通常很难在没有昂贵的大规模硬件配置的情况下复制。我的主要关注点是“不记录日志”和“记录日志”之间的时间差异可能会影响系统,导致错误不会发生。最终,性能降低的尺度很大,但幅度很小,所以我希望这不会成为问题。

System.Diagnostics.Trace作为DebugListeners集合的一部分运行,因此它的速度取决于最慢的监听器。默认的监听器会写入到Debugger.Log(如果正在记录)或系统的'OutputDebugString'。请注意:除非您需要将多个监听器附加到跟踪输出,否则在高性能日志记录情况下仍然使用Trace.WriteXX成本过高。如果必须写入调试输出,则应直接调用kernal32.dll上的OutputDebugString函数。(比Trace.WriteLine快至少50%) - headsling
System.Diagnostics v2中的TraceSource怎么样?与log4net相比,它的性能如何? - Eatdoku
5个回答

12

是的,相对于trace(跟踪工具),log4xxx更慢,因为trace通常是近核心工具,而log4xxx是一种更强大的工具。个人偏爱log4xxx,因为它更加灵活,但如果您需要的仅仅是在调试中使用,且不需要生产日志记录,那么只用trace就足够了。

注意:我之所以使用log4xxx,是因为同样适用于所有带有log4库的语言,而不仅仅是.Net。


6
您可能对Common.Logging库感兴趣。它是对现有日志记录实现的薄抽象包装,并允许您在运行时插入任何喜欢的日志框架。同时,正如我在关于性能的博客文章中所描述的那样,它比System.Diagnostics.Trace快得多。

祝好, Erich


4

根据我的经验,在大多数情况下,log4net的性能并不是一个问题。 真正的问题是,为什么你甚至需要在生产系统中“记录成千上万次”。 在我看来,在生产环境中,您应该仅记录最少量(信息和可能的警告级别),仅在需要时(在现场调试问题时)应激活调试级别。


1
日志记录在生产环境中是必不可少的!当出现问题时(它们肯定会出现,对吧?),日志通常是你唯一可以使用的工具。日志性能经常被忽视,直到它开始影响你的工作。Log4Net 不是为高性能/低影响而编写的。 - headsling

1
如果你想要兼顾两个方面,log4net可以允许你同时向aspnet tracer进行日志记录。当我想获取与我的日志记录中特定事件相关的性能统计数据时,我会打开这个选项。

0
刚刚进行了一个测试,比较了顺序写入简单文件和使用Log4Net完成相同任务的速度。与StreamWriter相比,Log4Net慢了约400倍。因此,如果您要写入大型日志文件,则我认为Log4Net不可用。但是,我发现它对于少量日志条目和调试非常有用。
也许在某些情况下,将日志记录隔离到单独的线程中可能是一个解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接