以下代码证明method1比method2更快。任何人都可以评论这种行为的原因是什么。
class Trial {
String _member;
void method1() {
for(int i=0;i<30480;i++) {
_member += "test";
}
}
void method2() {
String temp="";
for(int i=0;i<30480;i++) {
temp += "test";
}
_member = temp;
}
public static void main(String args[]) {
Trial t = new Trial();
long startTime1 = System.currentTimeMillis();
t.method1();
long endTime1 = System.currentTimeMillis();
long startTime2 = System.currentTimeMillis();
t.method2();
long endTime2 = System.currentTimeMillis();
System.out.println(endTime1 - startTime1);
System.out.println(endTime2 - startTime2);
}
}
答案 0 :(得分:12)
以下代码证明method1比method2
更快
没有。它没有证明它。
这取决于很多因素。当我运行此代码时,我得到了
1403
1248
因此,在我的环境中,您的代码“证明”method1比method2 更慢。
在进行基准测试时,您需要注意缓存和JVM预热等效果。
另见
了解更多信息。
我稍微重构了main
方法:
...
static void doBenchmark() {
Trial t = new Trial();
long startTime1 = System.currentTimeMillis();
t.method1();
long endTime1 = System.currentTimeMillis();
long startTime2 = System.currentTimeMillis();
t.method2();
long endTime2 = System.currentTimeMillis();
System.out.println(endTime1 - startTime1);
System.out.println(endTime2 - startTime2);
}
public static void main(String args[]) {
for (int i = 0; i < 20; i++) {
doBenchmark();
System.out.println("----");
}
}
这导致for
- 循环的第一次迭代的值相似,但随后结果收敛并且不再显着不同:
1396
1133
----
1052
1070
----
688
711
----
728
726
----
715
709
----
...
即使有时method1
似乎更快,有时method2
- 这很可能是由于测量不准确造成的。
答案 1 :(得分:0)
将jvm加热一段时间后,您会看到,方法2比方法1 更快。
这是我重新考虑的代码:
class Trial {
String _member;
void method1() {
for (int i = 0; i < 30480; i++) {
_member += "test";
}
}
void method2() {
String temp = "";
for (int i = 0; i < 30480; i++) {
temp += "test";
}
_member = temp;
}
public static void main(String args[]) {
Trial t = new Trial();
for (int i = 0; i < 10; i++) { //warm up jvm
t.method1();
t.method2();
}
t = new Trial();
long startTime1 = System.currentTimeMillis();
t.method1();
long endTime1 = System.currentTimeMillis();
long startTime2 = System.currentTimeMillis();
t.method2();
long endTime2 = System.currentTimeMillis();
System.out.println(endTime1 - startTime1);
System.out.println(endTime2 - startTime2);
}
}
结果如下:
----
2910
2894
----
但是对于实际的基准测试,你应该多次运行它并观察统计行为,然后才能得出任何结论!
答案 2 :(得分:0)
我已经修改了测试次数,但没有修改方法,这里使用 StringBuilder 2500在3000 时更快!
class Trial {
StringBuilder _member = new StringBuilder(243840);
void method1() {
for (int i = 0; i < 30480; i++) {
_member.append("test");
}
}
void method2() {
final StringBuilder temp = new StringBuilder(243840);
for (int i = 0; i < 30480; i++) {
temp.append("test");
}
_member = temp;
}
public static void main(final String args[]) {
long startTime1 = System.nanoTime();
new Trial().method1();
long endTime1 = System.nanoTime();
long startTime2 = System.nanoTime();
new Trial().method2();
long endTime2 = System.nanoTime();
System.out.println(endTime1 - startTime1);
System.out.println(endTime2 - startTime2);
System.out.println("------------------");
startTime1 = System.nanoTime();
new Trial().method1();
endTime1 = System.nanoTime();
startTime2 = System.nanoTime();
new Trial().method2();
endTime2 = System.nanoTime();
System.out.println(endTime1 - startTime1);
System.out.println(endTime2 - startTime2);
}
}
输出:
method1 then method2 with += in MILLIisecond
5563
5844
............................................
5437
6344
method2 then method1 with += in MILLIisecond
4625
5969
------------------
6531
4891
=====================================================
method1 then method2 with StringBuilder in NANOsecond
3530337
2074286
------------------
2058641
1983493
.....................................................
method2 then method1 with StringBuilder in NANOsecond
3430883
1698819
------------------
2065626
2144406
所以正如@Andreas所说,这不是测试表演的好方法。
要指出:使用声明大小的 StringBuilder (在Joshua Bloch的书中有效Java 项目51:注意字符串连接的性能)
- < em>在可能的情况下更喜欢method2():String [Builder]在其中被声明,而不是在外面使用