背景:mentor 在cr别人代码的时 发现有一句打印日志的代码

log.info("xxxxx {}",xxx.toString());复制代码

mentor 提示这边需要注意效率问题info级别跟系统打印日志级别相同 toString()方法一定会执行,但是如果为debug级别toString()方法会执行但是日志不会打印造成效率问题。

深入:

review代码时,发现太多人习惯log日志直接用“+”号连接。这是很不好的习惯。

In Logger, the logging methods are overloaded with forms that accept one, two or more values.[9] Occurrences of the simple pattern {} in the log message are replaced in turn with the values. This is simple to use yet provides a performance benefit when the values have expensive toString() methods. When logging is disabled at the DEBUG level, the logging framework does not need to evaluate the string representation of the values. In the following example, the values count or userAccountList only need to be evaluated when DEBUG is enabled; otherwise the overhead of the debug call is trivial.

private static final Logger LOG = LoggerFactory.getLogger(Wombat.class);
LOG.debug("There are now " + count + " user accounts: " + userAccountList); // slow
LOG.debug("There are now {} user accounts: {}", count, userAccountList);    // faster
123复制代码

如上面demo,请选择第二种书写方式。 原因1,第二种使用占位符只有当日志级别是debug,才会执行count和userAccountlist的toString方法,而第一种非debug级别也会执行。 原因2,更具可读性。

第一种无论是debug还是其他级别,都会执行输入值的toString方法,第二种只有在debug级别才会执行。

其次使用占用符 和使用string 字符拼接底层都是使用StringBuilder()进行实现。多字符情况下使用占位符效率会稍高。具体选择根据个人喜好。需要注意占位符个数少于传入实参的时候。不会报错,实参进行映射的时候会有一个顺序问题。使用sonarlint插件可以进行扫描避免这个问题。