背景

​ 上次在群中,有个群友说自己把所有项目中,所有使用占位符打印日志的方式都修改成为了字符串拼接的方式,因为他曾经看了一篇文章,说字符串拼接的形式比占位符形式的性能更好,这个话题引起了大家的广泛讨论。

​ 在我印象中,我记得曾经看过的文章说,占位符的方式性能好,因为如果不打日志的话,就不会进行字符串拼接,节省性能。最后抱着一探究竟的心态,我进行了一次日志输出方式的实验。

工具

IDEA + Gradle + JDK 8 + SpringBoot + Junit + Slf4j + logback

测试方式

本次测试我定义了4个方法,每个方法同时打印 DEBUG ,INFO 日志,默认日志级别是INFO级别的,所有DEBUG级别日志是不输出的,这样可以检测输出的日志会不会被不输出级别日志影响,同时我还给部分方法增加了if判断,这个是为了测试,我们是否有必要显性的进行日志级别的操作,具体代码如下:

 public void record(LogEntity logEntity) {
for (int i = 0; i < 1000; i++) {
if (log.isDebugEnabled()) {
log.debug("id:{},name:{},ip:{},url:{},params:{}",
logEntity.getId(),
logEntity.getName(),
logEntity.getId(),
logEntity.getUrl(),
logEntity.getParams());
}
log.info("id:{},name:{},ip:{},url:{},params:{}",
logEntity.getId(),
logEntity.getName(),
logEntity.getId(),
logEntity.getUrl(),
logEntity.getParams());
}
} public void record1(LogEntity logEntity) {
for (int i = 0; i < 1000; i++) {
log.debug("id:{},name:{},ip:{},url:{},params:{}",
logEntity.getId(),
logEntity.getName(),
logEntity.getId(),
logEntity.getUrl(),
logEntity.getParams());
log.info("id:{},name:{},ip:{},url:{},params:{}",
logEntity.getId(),
logEntity.getName(),
logEntity.getId(),
logEntity.getUrl(),
logEntity.getParams());
}
} public void record2(LogEntity logEntity) {
for (int i = 0; i < 1000; i++) {
if (log.isDebugEnabled()) {
log.debug("id:" + logEntity.getId() +
",name:" + logEntity.getName() +
",ip:" + logEntity.getId() +
",url:" + logEntity.getUrl() +
",params:" + logEntity.getParams());
}
log.info("id:" + logEntity.getId() +
",name:" + logEntity.getName() +
",ip:" + logEntity.getId() +
",url:" + logEntity.getUrl() +
",params:" + logEntity.getParams()); }
} public void record3(LogEntity logEntity) {
for (int i = 0; i < 1000; i++) {
log.debug("id:" + logEntity.getId() +
",name:" + logEntity.getName() +
",ip:" + logEntity.getId() +
",url:" + logEntity.getUrl() +
",params:" + logEntity.getParams());
log.info("id:" + logEntity.getId() +
",name:" + logEntity.getName() +
",ip:" + logEntity.getId() +
",url:" + logEntity.getUrl() +
",params:" + logEntity.getParams()); }
}

测试结果

我运行了6次Junit测试用例,结果如下:

结论

通过测试结果可以有以下发现:

字符串拼接的方法,大部分下情况性能高于占位符

如果采用占位符的方式,一定不要增加 log.isDebugEnabled()这种方式再显性的进行判断,否则性能会大大降低

昨天看到nacos项目,在翻看nacos源码的时候,发现针对日志输出这块,nacos也使用的字符串拼接

本文没有太高深的道理和原理,只是因为一个小的讨论,进行了一次实验,实验的过程和结果是否准确可靠还需要大家各自斟酌,同时希望借此抛砖引玉,能有大神给更加详细的解答。

github地址: https://github.com/Shiyajian/examples ,查看 spring-boot/chapter1/log

其他

自己写了个插件,可以打开CSDN的博客之后,自动展开全部内容,不用每次点【查看更多】,然后还需要登录那么麻烦了,github: https://github.com/Shiyajian/CSDN-clear.git

个人QQ好友群:757696438,吹牛扯淡为主,技术为辅,拒绝装逼,最欢迎妹子。

个人微信:q408859832 技术交流为主

备注:博客园

Java日志格式应该是占位符还是字符串拼接的更多相关文章

  1. Java{0}占位符替换字符串

    Java{0}占位符替换字符串 public class Test { public static void main(String[] args) { System.out.println(Stri ...

  2. js使用占位符替换字符串

    js使用占位符替换字符串是一个ES6中的模版字符串语法. 在``中使用 ${} var a = 5; var b = 10; console.log(`Fifteen is ${a + b} and ...

  3. 快速理解Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容的区别

    <Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?>老猿介绍了二者的区别,为了快速理解,老猿在此使用另外一种方式补充说明一下: 1.使用%r是调用objec ...

  4. Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?

    Python中使用百分号占位符的字符串格式化方法中%s和%r表示需要显示的数据对应变量x会以str(x)还是repr(x)输出内容展示. 关于str和repr的关系请见: <Python中rep ...

  5. 第3.8节 Python百分号占位符的字符串格式化方法

    一.    概念         格式化字符串就是将一些变量转换为字符串并按一定格式输出字符串,包括指定字符的位置.对齐方式.空位补充方式等.Python提供了多种字符串格式设置方法.本节先介绍一种简 ...

  6. Java替换字符串中的占位符

    在开发中,会有动态配置字符串其中的某些字符,如何使用字符中的占位符,并且在代码动态替换占位符实现动态配置字符串! 1.定义字符串时,再string文件添加字符串: 注意!记得要在字符文件中加上这些: ...

  7. java之mybatis之占位符

    1.mybatis中有两种占位符 #{}和 ${}. 2. #{} 占位符是为了获取值,获取的值用在 where 语句后,insert 语句后,update 语句. #{} 获取值,是根据值的名称取值 ...

  8. Java日志框架Slf4j+Log4j入门

    一.日志系统介绍 slf4j,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统.简答的讲就是slf4j是一系列的日志 ...

  9. Java日志框架SLF4J和log4j以及logback的联系和区别

    1.SLF4J(Simple logging Facade for Java) 意思为简单日志门面,它是把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口,使用时只需要按照其提供的接 ...

随机推荐

  1. 【转】 Pro Android学习笔记(七九):服务(4):远程服务的实现

    目录(?)[-] 远程服务的实现小例子 对外开放远程服务的接口 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flow ...

  2. 人物-IT-刘强东:刘强东

    ylbtech-人物-IT-刘强东:刘强东 刘强东,男,汉族,1973年3月10日生(另一说法:1974年2月14日),江苏宿迁人,祖籍湖南湘潭 .京东集团董事局主席兼首席执行官,本科毕业于中国人民大 ...

  3. Java常见设计模式之单例模式

         1.何为单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的 ...

  4. PHP二维数组,根据多个字段来排序

    如果是最最常见的二维数组排序, 大多数情况下也只用到二维: 用php内置函数 array_multisort( )  是最简单的: <?php 假设, $arr 是一个二维数组, $arg1是取 ...

  5. css菜鸟之HTML 中块级元素设置 height:100% 的实现

    HTML 中块级元素设置 height:100% 的实现 当你设置一个页面元素的高度(height)为100%时,期望这样元素能撑满整个浏览器窗口的高度,但大多数情况下,这样的做法没有任何效果. 为什 ...

  6. 数据库高手(DBA专家 ,SSIS,replacation ,tourble shooting)

    http://www.cnblogs.com/qanholas/category/266780.html 随笔分类 - mssql SQL Server 2008 Datetime Cast 成 Da ...

  7. Angular10 组件之间的通讯

    1 父组件和子组件之间的通讯 2 利用中间组件实现两个组件之间的通讯 3 利用服务实现两个组件之间的通讯 2017年8月26日20:09:13 待更新... 1 组件之间的关系图 1.1 父子关系 1 ...

  8. wpf label下划线不显示的问题

    突然发现label设置content的值为字符串时,如果字符串中包含_的话,在展示出来时下划线就不见了,百度了一下,发现了问题根源,说的label的ContentPresenter默认将下划线处理成快 ...

  9. 转:基于InfluxDB&Grafana的JMeter实时性能测试数据的监控和展示

    本文主要讲述如何利用JMeter监听器Backend Listener,配合使用InfluxDB+Grafana展示实时性能测试数据 关于JMeter实时测试数据 JMeter从2.11版本开始,命令 ...

  10. Linux kernel分析前的准备

    分析工具 “欲善其事,先利其器”.Linux内核的代码量非常大,如果没有一个好的察看分析工具,那将是一件非常繁琐的事情. Vim+cscope cscope,如果你知道ctags,那么它是一个比cta ...