简体   繁体   English

基于字符串创建的slf4j和log4j之间的区别

[英]Difference between slf4j and log4j on the basis of String creation

In log4j if we write 在log4j中,如果我们写

**logger.debug("Processing trade with id: " + id + " symbol: " + symbol);**

it will create String in string pool but when we use slf4j we use parameter based like this 它将在字符串池中创建String,但是当我们使用slf4j时,我们使用像这样的参数

**logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);**

So what is the difference between these two statement, slf4j will create String at run time or not ? 那么这两个语句有什么区别,slf4j会在运行时创建String吗?

The difference is increase of performance, in log4j the string is concatenated every time the line is evaluated even if log level is lower than debug so the string will never be used. 不同之处在于性能的提高,在log4j中,即使日志级别低于debug,每次计算行时字符串也会连接,因此永远不会使用该字符串。

slf4j, the string and parameters are passed through to the logger which only substitutes them if the log message is actually to be used. slf4j,字符串和参数被传递给记录器,只有在实际使用日志消息时才会替换它们。

Imagine code with debug statements every few lines, when in production and debug is disabled that is a huge amount of string manipulation that will never be used. 想象一下每隔几行使用调试语句的代码,当生产和调试被禁用时,这是一个永远不会被使用的大量字符串操作。

I would say to increase performance by reducing String concatenations . 我想说通过减少String concatenations来提高性能。

When you write this 当你写这个

"Processing trade with id: " + id + " symbol: " + symbol

You are creating the printing string manually. 您正在手动创建打印字符串。

When you write 当你写作

"Processing trade with id: {} and symbol : {} ", id, symbol
                    -------^id------------^symbol---------

In the second way before printing internally slf4j maintaind and generate a new string again with concatenation (Haven't check the source code,may be a StringBuilder ). 在内部打印之前的第二种方式slf4j维护并再次生成带有连接的新字符串(没有检查源代码,可能是StringBuilder )。

The {} called as place holders and replace by the args passed by you. {}称为占位符,并由您传递的args替换。

From docs of sl4j 来自sl4j的文档

This form avoids superfluous string concatenation when the logger is disabled for the DEBUG level. 当为DEBUG级别禁用记录器时,此表单可避免多余的字符串连接。 However, this variant incurs the hidden (and relatively small) cost of creating an Object[] before invoking the method, even if this logger is disabled for DEBUG. 但是,即使为DEBUG禁用了此记录器,此变量也会在调用方法之前产生隐藏(且相对较小)的创建Object []的成本。 The variants taking one and two arguments exist solely in order to avoid this hidden cost. 采用一个和两个参数的变体仅仅是为了避免这种隐藏的代价。

Read how to use the format : How to use java.String.format in Scala? 阅读如何使用格式: 如何在Scala中使用java.String.format?

SLF4J is basically an abstraction layer. SLF4J基本上是一个抽象层。 It is not a logging implementation. 它不是日志记录实现。 It means that if you're writing a library and you use SLF4J, you can give that library to someone else to use and they can choose which logging implementation to use with SLF4J eg log4j or the Java logging API. 这意味着如果您正在编写库并且使用SLF4J,则可以将该库提供给其他人使用,他们可以选择与SLF4J一起使用的日志实现,例如log4j或Java日志API。 It helps prevent projects from being dependent on lots of logging APIs just because they use libraries that are dependent on them. 它有助于防止项目依赖于大量日志记录API,因为它们使用依赖于它们的库。

使用Log4j2 API,我们可以使用logger.info(“String:{} int:{}。”,“Hello,World”,10);

So what is the difference between these two statement, slf4j will create String at rum time or not ? 那么这两个语句有什么区别,slf4j会在朗姆酒时刻创建String吗?

The strings will be created anyways irrespective of whether you use log4j or sl4j. 无论您使用的是log4j还是sl4j,都会创建字符串。 sl4j is offering a convenience of place holder. sl4j提供便利的占位符。

It is about String concatenation. 它是关于字符串连接。 First line always make String concat that expensive operation, second line is not concat if log level is not match debug. 第一行总是使String concat成为昂贵的操作,如果日志级别不匹配debug,则第二行不会连接。 I am not sure only presume, matching log level second option can be better performance because of internal StringBuilder usage. 我不确定只是假设,匹配日志级别第二个选项可以更好的性能,因为内部StringBuilder使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM