Java for循环优化 List flowers=new ArrayList();
我的for循环当前看起来像这样Java for循环优化 List flowers=new ArrayList();,java,coding-style,optimization,Java,Coding Style,Optimization,我的for循环当前看起来像这样 List<String> flowers = new ArrayList<String>(); for(int i=0;i
List<String> flowers = new ArrayList<String>();
for(int i=0;i
或者我应该把它改成下面给出的代码吗
for (int i = 0; i < flowers.size(); i++) {
...
}
int size=flowers.size();
对于(int i=0;i
哪一种性能更好(假设我有一大堆花),我猜应该是后者 最好用于每个循环[更具可读性]
int size = flowers.size();
for (int i = 0; i < size; i++) {
...
}
我使用
javap
转储了以下代码的指令:
for (Flower flower :flowers){
//...
}
当你看到冒号(:)时,读作
因此,上面的循环读作
“对于元素中的每个元素e。”注释
没有表现惩罚
用于使用for each循环,即使对于
数组。事实上,它可能会提供一点帮助
性能优于普通
在某些情况下,因为
计算数组索引的限制
只有一次。而你可以通过
手(第45项),程序员不需要
总是这样做
另见
// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
doSomething(e);
}
for(int i=0;i
来自Java语言规范(14.14.1):
basic for语句执行一些初始化代码,然后执行
表达式、语句和某些更新代码反复更新,直到
表达是错误的
在第一个示例中,表达式是i
,并且在每次迭代中对其求值一次。在您的特殊情况下,它不应该有明显的区别,因为ArrayList
上的flowers.getSize()
是一个非常短的方法。但是,一般来说,如果表达式的结果对于每次迭代都是相同的,并且代价高昂,那么就进行预计算
结果:这必须在Java虚拟机的每个实现中产生相同的输出,并证明该表达式在每个迭代中计算一次:
for (int i = 0; i < flowers.size(); i++) {
...
}
很抱歉,但是@Jigar的答案是错误的。这是正确的答案。(tldr;不要将
用于:每个
)
import java.util.ArrayList;
导入java.util.List;
公共类循环测试{
公共静态void main(字符串s[]{
漫长的开始,漫长的结束;
列表a=新的ArrayList();
对于(int i=0;i<2500000;i++){
a、 加(i);
}
/////测试:每个循环
start=System.currentTimeMillis();
for(整数j:a){
int x=j+3;
}
end=System.currentTimeMillis();
System.out.println(结束-开始
+“毫秒代表[整数j:a]”;
//////测试默认循环
start=System.currentTimeMillis();
对于(int i=0;i=0;){
int x=a.get(i)+3;
}
end=System.currentTimeMillis();
System.out.println(结束-开始
+“毫秒表示[int i=size;--i>=0;]”;
}
}
结果是:
import java.util.ArrayList;
import java.util.List;
public class LoopTest {
public static void main(String s[]) {
long start, end;
List<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 2500000; i++) {
a.add(i);
}
///// TESTING FOR : EACH LOOP
start = System.currentTimeMillis();
for (Integer j : a) {
int x = j + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ Integer j : a ] ");
////// TESTING DEFAULT LOOP
start = System.currentTimeMillis();
for (int i = 0; i < a.size(); i++) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = 0; i < a.length; i++ ] ");
////// TESTING SLIGHTLY OPTIMIZED LOOP
start = System.currentTimeMillis();
int size = a.size();
for (int i = 0; i < size; i++) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = 0; i < size; i++ ] ");
//// TESTING MORE OPTIMIZED LOOP
start = System.currentTimeMillis();
for (int i = size; --i >= 0;) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = size; --i >= 0; ] ");
}
}
[整数j:a]的96毫秒
[int i=0;i=0;]31毫秒
您可以自己决定,但是JVM优化器的属性太多了。您仍然需要对自己的代码进行灵活处理,并且使用for:each
表示法(几乎从来都不是)不是一个好主意。正如您所看到的,通过将大小放入它自己的变量中,您有了一个好主意
尽管其中一些优化可能依赖于JVM(有些可能会使用JIT),但了解Java做什么和不做什么很重要。任何一个都可以。根据JVM的不同,第二个时钟周期可能快几个时钟周期,但这将是一个无法测量或微不足道的差异。当心这些类型的子优化。除非您正在构建一个实时系统,在这个系统中,每一个CPU都计数,否则它们只会增加复杂性和更多的错误源 我建议使用迭代器构造(正如已经建议的那样)
它清晰、灵活且可预测。JVM无法优化它,因为
size()
是一种方法,JVM无法(也不会尝试)确定size()
在这个上下文中总是返回相同的值。提供<代码> siz()<代码>值不改变,第二个值稍微高一些,但增益如此之小,以至于您甚至不必考虑使用它。 如果数组列表在迭代过程中发生更改,则行为会有所不同。但我想你不会这么做的。根据我的测试,后者通常更快(特别是在像Android这样的系统上)。我将写如下:
for (Flower flower: flowers) { ...
for(inti=0,size=flowers.size();i
如果性能至关重要,请使用普通计数器循环,但是对于98%的情况,代码的清晰性和简单性更为重要(如1000倍或更高),您应该为每个循环使用一个计数器循环
@David指出使用计数器更快,但我要指出的是ev
int counter2 = 10;
for (int counter1 = 0; counter1 < counter2; counter1++) {
System.out.println(counter1 + ", " + counter2);
counter2--;
}
0, 10
1, 9
2, 8
3, 7
4, 6
import java.util.ArrayList;
import java.util.List;
public class LoopTest {
public static void main(String s[]) {
long start, end;
List<Integer> a = new ArrayList<Integer>();
for (int i = 0; i < 2500000; i++) {
a.add(i);
}
///// TESTING FOR : EACH LOOP
start = System.currentTimeMillis();
for (Integer j : a) {
int x = j + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ Integer j : a ] ");
////// TESTING DEFAULT LOOP
start = System.currentTimeMillis();
for (int i = 0; i < a.size(); i++) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = 0; i < a.length; i++ ] ");
////// TESTING SLIGHTLY OPTIMIZED LOOP
start = System.currentTimeMillis();
int size = a.size();
for (int i = 0; i < size; i++) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = 0; i < size; i++ ] ");
//// TESTING MORE OPTIMIZED LOOP
start = System.currentTimeMillis();
for (int i = size; --i >= 0;) {
int x = a.get(i) + 3;
}
end = System.currentTimeMillis();
System.out.println(end - start
+ " milli seconds for [ int i = size; --i >= 0; ] ");
}
}
96 milli seconds for [ Integer j : a ]
57 milli seconds for [ int i = 0; i < a.length; i++ ]
31 milli seconds for [ int i = 0; i < size; i++ ]
31 milli seconds for [ int i = size; --i >= 0; ]
for (Flower flower: flowers) { ...
for (int i = 0, size = flowers.size(); i < size; i++) {
...
}
[ int i = 0; i < size; i++ ]
1.6
-server
7.968242071 milli seconds for [ Integer j : a ]
7.206275775999999 milli seconds for [ int i = 0; i < a.length; i++ ]
1.5864E-5 milli seconds for [ int i = 0; i < size; i++ ]
14.774186076999998 milli seconds for [ int i = size; --i >= 0; ]
-client
83.36101683999999 milli seconds for [ Integer j : a ]
44.288568631 milli seconds for [ int i = 0; i < a.length; i++ ]
2.3191E-5 milli seconds for [ int i = 0; i < size; i++ ]
24.826621246 milli seconds for [ int i = size; --i >= 0; ]
1.7
-server
7.029150422 milli seconds for [ Integer j : a ]
6.6269827779999995 milli seconds for [ int i = 0; i < a.length; i++ ]
1.3852E-5 milli seconds for [ int i = 0; i < size; i++ ]
13.842110377 milli seconds for [ int i = size; --i >= 0; ]
13.868426141 milli seconds for [ int i = a.size()-1; i >= 0; i-- ]
1.6618000000000003E-5 milli seconds for [ int i = 0; i < a.size(); i++ ]
-client
7.382479727 milli seconds for [ Integer j : a ]
6.748068759 milli seconds for [ int i = 0; i < a.length; i++ ]
1.4162999999999998E-5 milli seconds for [ int i = 0; i < size; i++ ]
13.951547335999999 milli seconds for [ int i = size; --i >= 0; ]
13.929234053999998 milli seconds for [ int i = a.size()-1; i >= 0; i-- ]
1.6873E-5 milli seconds for [ int i = 0; i < a.size(); i++ ]
public static void main(String s[]) {
long start=0, end = 0, delta = 0;
//int[] a = new int[2500000];
List<Integer> a = new ArrayList<Integer>();
int x = 0;
for (int i = 0; i < 2500000; i++) {
a.add(i);
}
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.nanoTime();
for (Integer j : a) {
x = j + 3;
}
end = System.nanoTime();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ Integer j : a ] ");
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.nanoTime();
for (int i = 0; i < a.size(); i++) {
x = a.get(i) + 3;
}
end = System.nanoTime();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ int i = 0; i < a.length; i++ ] ");
int size = a.size();
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
x = a.get(i) + 3;
}
end = System.currentTimeMillis();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ int i = 0; i < size; i++ ] ");
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.nanoTime();
for (int i = size; --i >= 0;) {
x = a.get(i) + 3;
}
end = System.nanoTime();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ int i = size; --i >= 0; ] ");
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.nanoTime();
for (int i = a.size()-1; i >= 0; i--) {
x = a.get(i) + 3;
}
end = System.nanoTime();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ int i = a.size()-1; i >= 0; i-- ] ");
start=0; end = 0; delta = 0;
for (int ctr = 0; ctr < 1000; ctr++) {
start = System.currentTimeMillis();
for (int i = 0; i < a.size(); i++) {
x = a.get(i) + 3;
}
end = System.currentTimeMillis();
delta += end - start;
}
System.out.println(Math.pow(10, -6) * delta / 1000 + " milli seconds for [ int i = 0; i < a.size(); i++ ] ");
System.out.println(x);
}
Time for Original: 32552 ms Time for MicroOptimized 32707 ms
Fastest Loop: Original
Slowest loop takes 0.47616121897272057% more time
Time for Original: 274489 ms Time for MicroOptimized 30516 ms
Fastest Loop: MicroOptimized
Slowest loop takes 799.4920697339101% more time
public static void main(String[] args) {
List<Byte> list = initializeList();
byte value = 0;
final int NUM_LOOPS = 100;
long startOriginal, startOptimized, endOriginal, endOptimized;
startOptimized = System.currentTimeMillis();
for (int j = 0; j < NUM_LOOPS; j++) {
for (int i = -1, size = list.size(); ++i < size;) {
value = list.get(i);
}
}
endOptimized = System.currentTimeMillis();
startOriginal = System.currentTimeMillis();
for (int j = 0; j < NUM_LOOPS; j++) {
for (int i = 0; i < list.size(); i++) {
value = list.get(i);
}
}
endOriginal = System.currentTimeMillis();
System.out.println(value);
printResults(startOriginal, endOriginal, startOptimized, endOptimized);
}
private static void printResults(long startOriginal, long endOriginal,
long startOptimized, long endOptimized) {
long timeOriginal = endOriginal - startOriginal;
long timeOptimized = endOptimized - startOptimized;
long diff = Math.abs(timeOriginal - timeOptimized);
long min = Math.min(timeOriginal, timeOptimized);
System.out.println("Time for Original: " + timeOriginal + " ms"
+ " Time for MicroOptimized " + timeOptimized + " ms");
System.out.println("Fastest Loop: "
+ ((timeOriginal < timeOptimized) ? "Original"
: "MicroOptimized"));
System.out.println("Slowest loop takes " + ((double) 100 * diff / min)
+ "% more time");
}
public static List<Byte> initializeList(){
List<Byte> list = new ArrayList<Byte>();
final Byte ONE = new Byte((byte) 1);
for (int i = 0; i < Integer.MAX_VALUE / 10; i++) {
list.add(ONE);
}
return list;
}
}
for (Object object : aCollection) {
// Do something here
}
String d = JOptionPane.showInputDialog("enter start");
int s = Integer.parseInt(d);
String h = JOptionPane.showInputDialog("enter the end");
int z = Integer.parseInt(h);
for (int a = 1 ; a<10 ; a++) {
if (a%2 == 0 ) {
JOptionPane.showMessageDialog(null, a);
System.out.print(a);
}
}
import java.util.*;
public class TestForeach {
public static void main (String[] args) {
for (String s : getStrings()) {
System.out.println("The string was: "+s);
}
}
private static List<String> getStrings() {
System.out.println("IN GET STRINGS");
return Arrays.asList("A","B","C");
}
}
IN GET STRINGS
The string was: A
The string was: B
The string was: C
for (ConfigDataModel.VisaTypesBean.AddedBean visatype : visaTypesBeans) {
if (visatype.getId() == 24) {
}