Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java for循环优化 List flowers=new ArrayList();_Java_Coding Style_Optimization - Fatal编程技术网

Java for循环优化 List flowers=new ArrayList();

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

我的for循环当前看起来像这样

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项),程序员不需要 总是这样做


另见

只选择第一个变量,因为两个变量相同,但在第二个代码段中又创建了一个redundent int变量

因此,请看第一段代码

// 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) {

                            }