为什么少循环一行语句运行时间反而更长?

pape 2018-11-27 10:07:47
如下代码
		
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);


运行时间869ms
把for循环里第一行的element赋值语句注释掉,运行时间1230ms
为什么少运行一行语句,时间反而变长了?

如果循环次数从一百万改成二十万,就跟想象的一样,注释掉element赋值语句运行时间更短。

为什么循环一百万次是反过来的?
...全文
580 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
pape 2018-12-11
  • 打赏
  • 举报
回复
@oldmee 大神,太厉害了!试了一下,果然如此,换成随机数之后时间差不多了。谢谢。
oldmee 2018-11-29
  • 打赏
  • 举报
回复
for循环中element赋值操作是个简单操作,element保存的值会被下一次的new覆盖,所以在简单操作中String.ValueOf效率很高,并且会把值保存在堆中,下面的list.add是个复杂操作,但是add后的内容前面element赋值的时候已经初始化过了,在内存中开辟了一块空间,有一个hash值,而且计算机中正数与负数只是符号位不同罢了,所以list.add操作基本上等同于引用了上面已经创建好的String[]数组进行添加。 如果没有上面的简单操作,下面就是两个复杂操作,list.add 和 new String[]新建String对象两个,复杂操作搅在一起会让复杂度成倍的放大,于是运行时间反而更长,大概就是这么个意思。 你也可以试试把list.add后面String数组里的i换成与i无关的数字,比如 Random.nextInt(100),你会发现不管有没有上面那条element赋值语句时间花费都差不多(element的赋值是简单操作,基本上不耗时间),你自己体会一下。
ITKingofNeighbor 2018-11-29
  • 打赏
  • 举报
回复
jdk 版本影响???
  • 打赏
  • 举报
回复
引用 10 楼 剑心通明 的回复:
我这里,一个是592,注释了是568,好像没问题啊
我用的win10+jdk1.8 注释调之后确实满了几百毫秒,我让同事的win7试了结果是没差别
  • 打赏
  • 举报
回复
我这里,一个是592,注释了是568,好像没问题啊
pape 2018-11-27
  • 打赏
  • 举报
回复
这是完整的代码,哪位大侠也运行一遍看看,我在别人的机器上运行也是这个结论。一直不明白为什么。



import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Cool {

public static void main(String[] args) {
new Cool().run();
}

public void run() {
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);
System.out.println(list.size());
}

}

  • 打赏
  • 举报
回复
理论上不可能,可能楼主本地环境或者内存什么的问题。
  • 打赏
  • 举报
回复
我的也是,注释调之后更慢了
pape 2018-11-27
  • 打赏
  • 举报
回复
谢谢nayi_224,我在linux服务器上运行了,得出了一样的结论是正常的。但是在我本地,还是老样子。可能是本地环境的问题,奇怪的是我在别人的机器上运行也是一样的奇怪,win10专业版环境。
nayi_224 2018-11-27
  • 打赏
  • 举报
回复


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Cool {

	public static void main(String[] args) {
		new Cool().run();
	}

	public void run() {
		List<String[]> list = new ArrayList<>();
		long start = System.currentTimeMillis();
		String[] element;
		for (int i = 0; i < 1000000; i++) {
			element = new String[] { String.valueOf(i), String.valueOf(i) };
			list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
		System.out.println(list.size());
	}

}


2217 1000000

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Cool {

	public static void main(String[] args) {
		new Cool().run();
	}

	public void run() {
		List<String[]> list = new ArrayList<>();
		long start = System.currentTimeMillis();
		String[] element;
		for (int i = 0; i < 1000000; i++) {
			//element = new String[] { String.valueOf(i), String.valueOf(i) };
			list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
		}
		long end = System.currentTimeMillis();
		System.out.println(end - start);
		System.out.println(list.size());
	}

}
1640 1000000 运行了几次,平均都差了700左右
pape 2018-11-27
  • 打赏
  • 举报
回复
非常感谢@LCL_data

我改用依次执行的方式,也得出来,执行一条时间更短

1000000 Both
892
1000000 One
265


但是如果我不是依次执行,而是先单独执行两条的,然后注释掉一条,再重新执行,就会出现,注释掉一条之后执行时间更长的结果。不知道为什么。求大神指点!

下面这个,我先注释掉下面那段,执行上面那段两条语句的,时间是878ms,然后注释掉两条语句的,放开下面那段一条语句的,时间是1238ms。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Cool {

public static void main(String[] args) {
new Cool().run();
}

public void run() {
System.out.println("1000000 Both");
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);

System.out.println("1000000 One");
List<String[]> list1 = new ArrayList<>();
long start1 = System.currentTimeMillis();
String[] element1;
for (int i = 0; i < 1000000; i++) {
//element1 = new String[] { String.valueOf(i), String.valueOf(i) };
list1.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);
}

}
十八道胡同 2018-11-27
  • 打赏
  • 举报
回复
package com.demo;

import java.util.ArrayList;
import java.util.List;

public class Test08 {
public static void main(String[] args) {
System.out.println("1000000 Both");
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);

System.out.println("1000000 One");
List<String[]> list2 = new ArrayList<>();
long start2 = System.currentTimeMillis();
String[] element2;
for (int i = 0; i < 1000000; i++) {
//element2 = new String[] { String.valueOf(i), String.valueOf(i) };
list2.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);

System.out.println("200000 Both");
List<String[]> list1 = new ArrayList<>();
long start1 = System.currentTimeMillis();
String[] element1;
for (int i = 0; i < 200000; i++) {
element1 = new String[] { String.valueOf(i), String.valueOf(i) };
list1.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);

System.out.println("200000 One");
List<String[]> list3 = new ArrayList<>();
long start3 = System.currentTimeMillis();
String[] element3;
for (int i = 0; i < 200000; i++) {
//element3 = new String[] { String.valueOf(i), String.valueOf(i) };
list3.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end3 = System.currentTimeMillis();
System.out.println(end3 - start3);
}
}


1000000 Both
1065
1000000 One
249
200000 Both
98
200000 One
15
十八道胡同 2018-11-27
  • 打赏
  • 举报
回复
package com.demo;

import java.util.ArrayList;
import java.util.List;

public class Test08 {
public static void main(String[] args) {
System.out.println("1000000 Both");
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);

System.out.println("1000000 One");
List<String[]> list2 = new ArrayList<>();
long start2 = System.currentTimeMillis();
String[] element2;
for (int i = 0; i < 1000000; i++) {
//element2 = new String[] { String.valueOf(i), String.valueOf(i) };
list2.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);

System.out.println("200000 Both");
List<String[]> list1 = new ArrayList<>();
long start1 = System.currentTimeMillis();
String[] element1;
for (int i = 0; i < 1000000; i++) {
element1 = new String[] { String.valueOf(i), String.valueOf(i) };
list1.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);

System.out.println("200000 One");
List<String[]> list3 = new ArrayList<>();
long start3 = System.currentTimeMillis();
String[] element3;
for (int i = 0; i < 1000000; i++) {
//element3 = new String[] { String.valueOf(i), String.valueOf(i) };
list3.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end3 = System.currentTimeMillis();
System.out.println(end3 - start3);
}
}


1000000 Both
1053
1000000 One
888
200000 Both
1079
200000 One
145

3楼的搞错了
十八道胡同 2018-11-27
  • 打赏
  • 举报
回复
package com.demo;

import java.util.ArrayList;
import java.util.List;

public class Test08 {
public static void main(String[] args) {
System.out.println("1000000 Both");
List<String[]> list = new ArrayList<>();
long start = System.currentTimeMillis();
String[] element;
for (int i = 0; i < 1000000; i++) {
element = new String[] { String.valueOf(i), String.valueOf(i) };
list.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end = System.currentTimeMillis();
System.out.println(end - start);

System.out.println("1000000 One");
List<String[]> list2 = new ArrayList<>();
long start2 = System.currentTimeMillis();
String[] element2;
for (int i = 0; i < 1000000; i++) {
element2 = new String[] { String.valueOf(i), String.valueOf(i) };
list2.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end2 = System.currentTimeMillis();
System.out.println(end2 - start2);

System.out.println("200000 Both");
List<String[]> list1 = new ArrayList<>();
long start1 = System.currentTimeMillis();
String[] element1;
for (int i = 0; i < 1000000; i++) {
element1 = new String[] { String.valueOf(i), String.valueOf(i) };
list1.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);

System.out.println("200000 One");
List<String[]> list3 = new ArrayList<>();
long start3 = System.currentTimeMillis();
String[] element3;
for (int i = 0; i < 1000000; i++) {
element3 = new String[] { String.valueOf(i), String.valueOf(i) };
list3.add(new String[] { String.valueOf(i*(-1)), String.valueOf(i*(-1)) });
}
long end3 = System.currentTimeMillis();
System.out.println(end3 - start3);
}
}



1000000 Both
1125
1000000 One
356
200000 Both
786
200000 One
249

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧