- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试找到解决由于使用以下形式的代码而导致的冗余字符串连接问题的最佳方法:
logger.debug("Entering loop, arg is: " + arg) // @1
在大多数情况下,logger.level
高于 debug
,并且 arg.toString()
和字符串连接是一种浪费,耗尽 CPU 周期并短暂耗尽内存。
在引入可变参数之前,推荐的方法是首先测试记录器级别:
if (logger.isDebugEnabled())
logger.debug("Entering loop, arg is: " + arg); // @2
但现在首选的形式是
logger.debug("Entering loop, arg is: {}", arg); // @3
在脚本中为每个 logger.debug
加上 if (logger.isDebugEnabled())
(以及其他方法的等价物)前缀并不是很困难,但是我正在尝试找到将第一种形式转换为第三种形式的最佳方法。
有什么建议吗?挑战在于在格式字符串中插入正确的数字大括号对 {}
。我希望 logback 能够在末尾附加占位符未涵盖的剩余参数,但我找不到它执行此操作的引用。
作为替代方案,我正在考虑编写一个粘贴在末尾的类Concatenator
并将第一种形式转换为
logger.debug(new Concatenator("Entering loop, arg is: ", arg)); // @4
Concatenator
类延迟对 arg.toString()
的调用和字符串连接,直到 logger
调用 toString()
,从而在记录器处于较高过滤级别时避免这两种情况。它确实增加了创建 Object[]
和 Concatenator
的开销,但这应该比替代方案便宜。
问题:
@1->@4
- 将+
替换为,
并包含在new Contatenator( ...)
) 更容易。我有什么遗漏的吗?@4
比 @1
好得多,我这样说对吗?public class Concatenator {
final Object[] input;
String output;
public Concatenator(Object... input) {
this.input = input;
}
public String toString() {
if (output == null) {
StringBuffer b = new StringBuffer();
for (Object s : input) b.append(s.toString());
output = b.toString();
}
return output;
}
public static void main(String args[]) {
new Concatenator("a", "b", new X());
System.out.println(new Concatenator("c", "d", new X()));
}
}
class X {
public String toString() {
System.out.println("X.toString");
return super.toString();
}
}
最佳答案
不幸的是,你的方法不会改变任何事情。事实上,它引入了一个额外的对象实例化/分配(您的连接器)。您还使用了 StringBuffer
,它引入了您不需要的同步开销。
问题出在 SLF4J 的 Logger.debug()
调用的方法签名上。第一个参数始终是String
。这意味着您必须调用:
logger.debug(new Concatenator("Entering loop, arg is: ", arg).toString());
这意味着...您所做的事情与 Java 要做的事情完全相同,但开销更大。
Java 编译器通过创建 StringBuilder
并执行您在 Concatenator
中所做的操作来处理字符串连接运算符 (+
) toString()
上的类。
logger.debug("Entering loop, arg is: " + arg);
变成:
logger.debug(new StringBuilder()
.append("Entering loop, arg is: ")
.append(arg).toString());
(如果您使用 javap
查看生成的字节码,您会发现情况就是如此。)
因此,您当前的方法将比现在的方法更昂贵。
编辑:因此,完成这项工作的方法是......
logger.debug("{}", new Concatenator("Entering loop, arg is: ", arg));
这样,您的Concatenator
就会作为Object
传递,除非记录器需要,否则不会调用它的toString()
。另外,将类中的 StringBuffer
替换为 StringBuilder
。
如果我没有直接回答你的问题......这比原来的更好吗? 可能;除非需要,否则不会发生字符串连接。然而,您正在引入对象实例化/分配。查看差异的唯一真正方法是对其进行分析/编写基准。
关于java - 将 logger.debug ("message: "+ 文本)转换为 logger.debug(消息 : {}", 文本),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21718213/
作为一个新人中的菜鸡,最近在看一个项目的代码其中有这么一段看得我很是费解 public class AssembleMsgService { private static Logger logger
我已更改 Gradle 构建脚本以使用 Spring 2.0.1 而不是 1.5.9。当我运行 gradle build 时,出现错误:找不到符号 Logger logger = Logger.get
这是我的示例代码: public class Logs { private static Logs logHandler; public static Logs handler() {
我目前正在使用 Java 日志记录。我有一个记录器 cwh.A 和 cwh.B。是否可以通过 Java 从记录器 cwh 获取这些记录器,而不知道它们的名称? 最佳答案 可以通过日志管理器获取所有记录
在我的应用程序中,有一次我将 java.util.logging 的根 Logger 及其所有处理程序设置为 Level.FINEST,如下所示: Logger.getLogger("").setLe
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 7 年前。 Improv
我刚刚将 Java 插件升级到 1.7.0_25,这导致我几年前编写的一个小程序出现 fatal error (此后一直在维护)。 在小程序的 init() 方法的早期,我调用了 logger = L
logger.debug 和 logger.info 有什么区别? logger.debug什么时候打印? 最佳答案 我建议你看看这篇名为 "Short Introduction to log4j"
Fixed I tried reinstalling the plugin but that didn't work so i completely cleared my inteljii idea
我定义了一个记录器实例如下: private static final Logger LOGGER = Logger.getLogger(Main.class.getName()); 我有一个要记录的
我正在 Windows 下使用 Python 3.4.2。就我而言, import logging logger = logging.getLogger('logger') logger.setLev
我目前正在使用 C# 开发一个新的 Prism 项目,并想在我的 Bootstrapper 类中创建一个 NLog Logger。不幸的是,无论我做什么,它都拒绝构建,并告诉我... 'Logger.
我已经有几年没有使用 Log4J 了。我现在正在使用 org.jboss.logging 包在 JBoss 5 下开发一个应用程序。当我以前这样做时,将 logger.info() 消息包含在日志记录
ActiveRecord::Base.logger = Logger.new(STDOUT) 的 redis 等价物是什么?我想看看redis在做什么。 最佳答案 $redis.client.logg
我正在尝试使用 log4js 创建日志文件。完成所有配置后运行 Node app.js 时,我收到以下错误。 错误: TypeError: logger.setLevel is not a funct
我在一个拥有大约 50 多名开发人员的 IT 部门工作。它曾经有大约 100 多名开发人员,但由于经济衰退而被削减。 当我们的部门规模扩大时,我们雄心勃勃地努力建立一个特殊的架构小组。 这个小组决定做
我正在尝试找出跨多个模块使用 python 日志记录的最佳实践。我在这里看到:http://docs.python.org/2/howto/logging#logging-from-multiple-
我想将 Logger 注入(inject)到在 WildFly 10 上运行的 Maven 动态 Web 项目中的 bean 中。 我在 POM 中添加了依赖项。 WildFly 中提供了范围:
Java 9 引入了一个新的记录器,即 java.lang.System.Logger但我们总是有java.util.logging.Logger . 此记录器有什么新功能以及它有何改进? 最佳答案
我在 eclipse Mars 中配置了我的环境,但是 log4j 出现错误。我使用 spring 4 和 Maven 作为依赖管理器。部分代码: Eclipse 在这一行显示了一个错误,等于后的第二
我是一名优秀的程序员,十分优秀!