Enhanced for loop performance worse than traditional indexed lookup?

后端 未结 4 1458
小蘑菇
小蘑菇 2020-12-16 01:38

I just came across this seemingly innocuous comment, benchmarking ArrayList vs a raw String array. It\'s from a couple years ago, but the OP writes

I

4条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-16 02:14

    The problem you have is that using an Iterator will be slower than using a direct lookup. On my machine the difference is about 0.13 ns per iteration. Using an array instead saves about 0.15 ns per iteration. This should be trivial in 99% of situations.

    public static void main(String... args) {
        int testLength = 100 * 1000 * 1000;
        String[] stringArray = new String[testLength];
        Arrays.fill(stringArray, "a");
        List stringList = new ArrayList(Arrays.asList(stringArray));
        {
            long start = System.nanoTime();
            long total = 0;
            for (String str : stringArray) {
                total += str.length();
            }
            System.out.printf("The for each Array loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
        }
        {
            long start = System.nanoTime();
            long total = 0;
            for (int i = 0, stringListSize = stringList.size(); i < stringListSize; i++) {
                String str = stringList.get(i);
                total += str.length();
            }
            System.out.printf("The for/get List loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
        }
        {
            long start = System.nanoTime();
            long total = 0;
            for (String str : stringList) {
                total += str.length();
            }
            System.out.printf("The for each List loop time was %.2f ns total=%d%n", (double) (System.nanoTime() - start) / testLength, total);
        }
    }
    

    When run with one billion entries entries prints (using Java 6 update 26.)

    The for each Array loop time was 0.76 ns total=1000000000
    The for/get List loop time was 0.91 ns total=1000000000
    The for each List loop time was 1.04 ns total=1000000000
    

    When run with one billion entries entries prints (using OpenJDK 7.)

    The for each Array loop time was 0.76 ns total=1000000000
    The for/get List loop time was 0.91 ns total=1000000000
    The for each List loop time was 1.04 ns total=1000000000
    

    i.e. exactly the same. ;)

提交回复
热议问题