当前位置: 首页 > 面试题库 >

数组创建与字符串串联的日志记录方法哪个具有更好的性能?

彭成天
2023-03-14
问题内容

在传递多个字符串进行记录时,最好使用varargs或字符串连接吗?

在生产环境中将禁用日志记录。

考虑以下代码,

public void log(int logLevel, String ... msg) {
    if (logLevel >= currentLogLevel) {
        for (String m : msg) {
            // print the log to file
        }
    }
}
// calling
log(2, "text1", var1, "text2");

VS.

public void log(int logLevel, String msg) {
    if (logLevel >= currentLogLevel) {
        // print the log to file
    }
}
// calling
log(2, "text1" + var1 + "text2");

哪一个在两种情况下都表现良好(启用/禁用)?


问题答案:

这些都不是特别好。varargs会更好地执行,因为它不进行String连接,这比数组创建要昂贵得多,但是由于您使用的是Stringvarargs而不是Objectvarargs,因此
即使在生产环境中* ,也toString()必须在所有对象上调用该方法,会比较贵。 *

但是,不要害怕!这是一个已 解决的问题
。SLF4J(Java简单日志记录门面)已经找到了为您完成此操作的最佳方法。如果使用SLF4J实现(最常见的两个是Log4J和Logback),则可以使用参数化的日志记录参数:

更好的选择

存在一种基于消息格式的便捷替代方法。假设条目是一个对象,您可以编写:

Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);

只有在评估是否记录日志之后,并且只有在决定是肯定的情况下,记录器实现才会格式化消息,并将“
{}”对替换为entry的字符串值。换句话说,禁用log语句时,此格式不会产生参数构造的开销。

以下两行将产生完全相同的输出。但是,在禁用日志记录语句的情况下,第二个变体将比第一个变体好 至少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纳秒。



 类似资料:
  • 我的代码正在工作,但我认为这是一种糟糕的方法。(使用 system() 存在安全问题,并且仅仅因为不接受 ss.str() 而创建字符串)。你知道更好的方法吗? argv[2] 来自: int main (int argc, char *argv[]) {... 有更好的主意吗?

  • 我正在使用Scala将文件写入磁盘。 为了创建将写入文件的整个字符串,我目前正在迭代我的数据,并将所有信息附加到StringBuilder对象。 例如: 在操作结束时,我调用StringBuilder的toString方法,并写入路径。 我知道Scala对Strings有编译优化,所以我的问题是: 哪种方法的性能更好。字符串插值连接还是StringBuilder? 这些编译优化是否与StringB

  • 问题内容: 哪种资本化方法更好? 矿: 要么 公用语言-StringUtils.capitalize: 我认为我更好,但我宁愿问。 问题答案: 表现是平等的。 您的代码复制了char []调用和。 关于Apache代码和。apache代码有一个额外的字符串实例,该实例具有基本char [1,length]内容。但这在创建实例String时不会被复制。

  • 本文向大家介绍字符串拼接有哪些方式?哪种性能好?相关面试题,主要包含被问及字符串拼接有哪些方式?哪种性能好?时的应答技巧和注意事项,需要的朋友参考一下 性能最好的是连接: 继续补充:

  • 问题内容: 在过滤掉冗余信息时,我需要组合两个字符串集,这是我想出的解决方案,有没有人可以建议的更好方法?也许我忽略了内置的东西?谷歌没有任何运气。 问题答案: 由于a 不包含重复的条目,因此可以通过以下方式将两者合并: 两次添加都没有关系,该集合只包含一次元素…例如,不需要使用method 进行检查。

  • 问题内容: 我正在从事Java代码优化。我不清楚或符号之间的区别: 第2行和第3行有什么区别? 问题答案: 这种方法使用StringBuilder创建结果字符串 此方法仅调用的静态方法来获取int的String版本 依次调用