在效率和原始性能方面,如果我想打印出string
的列表,我应该先将它们连接起来,然后打印出来,还是应该逐个打印出来?
例如:
List<String> strings = whatever;
//Option 1
for(String s : strings){
System.out.println(s);
}
//Option 2
String output = "";
for(String s : strings){
output = output + s + "\n";
}
System.out.print(output);
选项1或选项2更快吗?
答案 0 :(得分:0)
选项1的复杂性是线性的。选项2是二次的,因为字符串是不可变的,并且每次在末尾附加某些内容时都必须创建一个新的字符串。因此,给定足够大的strings
数组,选项1将始终更快。
很难衡量,因为System.out.println
使用不同的线程来打印该行。虽然电话很重,但人们都知道。因此,如果我猜测,我认为以下是最好的选择:
StringBuilder output = new StringBuilder();
for(String s : strings) {
output.append(s);
}
System.out.println(s);
这使它线性且非常快。
答案 1 :(得分:0)
我建议尝试两种方式,看看哪种方式更快。 String
连接是一项昂贵的操作,但System.out.println()
也是如此,所以正确的做法很可能取决于您的用例。就个人而言,我在尝试打印太长的String
时遇到了问题,但println()
太贵了。
答案 2 :(得分:0)
我认为string
中包含的list
是final
。
如果它们未被声明为final
,它们应该是。
如果它们被声明为final
,我认为第二个选择会更快,因为string
s的连接是用final
个变量完成的。
答案 3 :(得分:0)
选项2明显变慢。
在选项1中,使用'for each'循环等效于使用迭代器来访问List。 它是一个只读访问权限,不需要在内存中存储任何额外的存储空间,不需要复制和粘贴任何内容,也不需要占用任何空间,因此它不会产生任何“浪费”。点击此处了解How does the Java 'for each' loop work?
与选项2相比,您创建了一个新对象,只是在执行此操作时进行垃圾回收。
String output =“”;
以及每次这个
output = output + s +“\ n”;
发生,创建一个新的String对象,并从旧的String对象进行复制和粘贴。并且引用'output'继续为新的String对象工作,让旧的String对象单独驻留在内存中,等待垃圾回收。发生这种情况是因为java String的属性,一旦创建它就是不可变的意义,它永远不会被改变。又名所有String都是最终创建的。详细了解Immutability of Strings in Java
从System.out.println()函数开始,它只需要一段时间,因此就Big O符号分析而言,它是可以忽略的。
这个问题是一个很好的例子,为什么你应该使用StringBuilder或StringBuffer来操纵java中的String。 Why StringBuilder when there is String?
答案 4 :(得分:0)
首先,对于任何性能问题,您只需使用
进行自我测量即可System.currentTimeMillis();
你应该在循环之前和循环之后运行它并检查结果。
第二,更重要的是:你的第二个选择是 NO NO!永远不要这样做。让我给你一个类比:说你正在画道路白线。你把你的油漆桶放在0点,然后画出你的第一行。然后,你回到你的水桶,以获得更多的油漆,并移动到第二行。然后你回到0点以获得更多的油漆并移动以绘制第3行。等等等等。
在某种程度上,不是随身携带水桶 - 而是将它留在第0点。你在某一点上会非常慢。提示:使用StringBuilder或StringBuffer