我刚开始使用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等)相比如何?
答案 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来连接由“ +”运算符分隔的一系列文字,这是合理的表现。