这些都没有表现得特别好。可变参数会表现得更好,因为它不这样做String
连接,这是一个比数组创建更昂贵的操作,但因为您正在使用String
可变参数而不是Object
可变参数toString()
必须在所有对象上调用方法即使在生产中,这会相对昂贵。
不过,不用害怕!这是一个解决了问题. SLF4J(Java 的简单日志外观)已经找到了为您做到这一点的最佳方法。如果您使用 SLF4J 实现(最常见的两个是Log4J and Logback),你可以使用参数化日志参数:
更好的选择
存在一种基于消息格式的便捷替代方案。假设entry是一个对象,你可以这样写:
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
仅在评估是否记录后,并且仅当决定是肯定的时,记录器实现才会格式化消息并将“{}”对替换为条目的字符串值。换句话说,这种形式在禁用日志语句时不会产生参数构造的成本。
以下两行将产生完全相同的输出。但是,在禁用日志记录语句的情况下,第二个变体将优于第一个变体至少 30 倍。
logger.debug("The new entry is "+entry+".");
logger.debug("The new entry is {}.", entry);
还可以使用两个参数的变体。例如,你可以写:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
如果需要传递三个或更多参数,则还可以使用 Object[] 变体。例如,你可以写:
Object[] paramArray = {newVal, below, above};
logger.debug("Value {} was inserted between {} and {}.", paramArray);
请注意,在第一种和第二种情况下,它不会创建临时数组,如果 SLF4J 中不需要,则存在方法签名,以便不创建数组。 这是完整的文档,您可以在其中看到所有不同的方法签名
如果您决定使用Logback
,你应该知道方法调用的成本当日志记录关闭时大约是20纳秒。充分讨论Logback的性能:
您可以通过将根记录器的级别设置为 Level.OFF(可能的最高级别)来完全关闭日志记录。当日志记录完全关闭时,日志请求的成本包括方法调用加上整数比较。在 3.2Ghz Pentium D 机器上,此成本通常约为 20 纳秒。