Java中的字符串连接相对于其他编译语言有多慢/快?

时间:2018-08-24 14:11:33

标签: java benchmarking

我刚开始使用Java,在阅读this guide的同时,我注意到以下片段,描述了Junit框架的最新更新。

  

我们现在可以在JUnit 5的lambda中编写断言消息,从而允许   懒惰的评估以跳过复杂的消息构建,直到需要:

@Test
public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation() {
    Assertions.assertTrue(
      2 == 3, 
      () -> "Numbers " + 2 + " and " + 3 + " are not equal!");
}

作为Java的新手,这感觉很不错,只是为了解决字符串连接问题。

使用Java评估字符串是否真的那么慢(相对于其他语言?)。与其他编译语言(如C,Golang等)相比如何?

2 个答案:

答案 0 :(得分:4)

重点是:Java中没有 lazy 字符串格式。

意思是,在诸如C之类的语言中,您可能会看到诸如以下内容:

#define debug_print...

(请参见一些真实的示例here

这个想法是定义一个宏,您将复杂的字符串传递给该宏。但是编译器确保仅在实际存在该字符串的情况下生成代码。

含义:当使用debug_print()时,构建真正传递给宏调用的消息可能仅需要复杂的字符串concat,会在确实需要该消息时发生!邮件是延迟连接的。

在Java中,我们根本无法表达它。你总是要走

if (someCondition) {
  then pull together that large string

不好,尤其是在进行跟踪时。我们小组中的某些人编写了该代码,而每个trace语句都具有前导if语句实在是太令人讨厌了。这样会使整个代码的可读性大大降低。

因此:关于字符串连接的成本,这完全不是完全。如果确实需要该字符串,则花费所需的CPU周期。

并回答一个实际的问题:最后,当该代码被足够频繁地调用时,JIT仍将其转换为经过仔细优化的机器代码。因此:实际的字符串concat并不是问题。

换句话说:您不会以源代码的形式考虑Java的“性能”。重要的是JIT在运行时会发生什么。

答案 1 :(得分:0)

这是底线。从Java开始,不用担心诸如String级联之类的次要性能问题。对于大型应用程序服务器来说,这可能是个小问题,其中完成了许多String连接,但未使用结果。一个示例是日志记录,其中的日志级别导致事件被忽略。此外,Java使用StringBuilder来连接由“ +”运算符分隔的一系列文字,这是合理的表现。