list.ensureCapacity竟然会变慢
jdk1.8
应该是做了优化了;
public class Test10 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); long beginTime = System.currentTimeMillis(); for (int i = 0; i < Integer.MAX_VALUE / 300; i++) { list.add(i); } long endTime = System.currentTimeMillis(); CusPrint.print(endTime - beginTime); // 344 } } public class Test11 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); // ArrayList<Integer> list = new ArrayList<>(Integer.MAX_VALUE/300); // 这样也挺慢的 CusPrint.print("---"); list.ensureCapacity(Integer.MAX_VALUE/300); // 这样竟然比不加这句要慢 CusPrint.print("---"); long beginTime = System.currentTimeMillis(); for (int i = 0; i < Integer.MAX_VALUE / 300; i++) { list.add(i); } long endTime = System.currentTimeMillis(); CusPrint.print(endTime - beginTime); // 3391 } }
测了一下还是数组快:
beginTime2 = System.currentTimeMillis(); int [] arr1 = new int[Integer.MAX_VALUE/300]; for(int i=0;i<Integer.MAX_VALUE/300;i++) { arr1[i] = i; } endTime2 = System.currentTimeMillis(); CusPrint.print(endTime2 - beginTime2); // 59
放到一起,修改一下list的最大容量,数组就是快,使用了ensureCapacity就是慢;
public class Test11_2 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); CusPrint.print("---"); int capacity = Integer.MAX_VALUE/30; list.ensureCapacity(capacity); // 这样竟然比不加这句要慢 CusPrint.print("---"); long beginTime = System.currentTimeMillis(); for (int i = 0; i < capacity; i++) { list.add(i); } long endTime = System.currentTimeMillis(); CusPrint.print(endTime - beginTime); // 26524 CusPrint.print("---------------"); ArrayList<Integer> list2 = new ArrayList<>(); long beginTime2 = System.currentTimeMillis(); for (int i = 0; i < capacity; i++) { list2.add(i); } long endTime2 = System.currentTimeMillis(); CusPrint.print(endTime2 - beginTime2); // 20126 CusPrint.print("---------------"); for(int i=0;i<capacity;i++) { if(i<capacity) { } } CusPrint.print("---------------"); for(int i=0;i<capacity;i++) { if(i<i+1) { } } CusPrint.print("---------------"); beginTime2 = System.currentTimeMillis(); int [] arr1 = new int[capacity]; for(int i=0;i<capacity;i++) { arr1[i] = i; } endTime2 = System.currentTimeMillis(); CusPrint.print(endTime2 - beginTime2); // 47 CusPrint.print("---------------"); } }
改到Integer.MAX_VALUE/3;直接就OOM了;
list.ensureCapacity(capacity); // 就是这句就可以OOM
异常:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3210) at java.util.Arrays.copyOf(Arrays.java:3181) at java.util.ArrayList.grow(ArrayList.java:265) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239) at java.util.ArrayList.ensureCapacity(ArrayList.java:219) at com.stono.thread3.page_arraylist.Test11_2.main(Test11_2.java:14)
你在凝望深渊的时候,深渊也在凝望你,别看太久。
哈哈,再看会儿:
使用list.trimToSize();竟然可以变快;
public class Test30 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.ensureCapacity(Integer.MAX_VALUE / 300); list.trimToSize(); long beginTime = System.currentTimeMillis(); for (int i = 0; i < Integer.MAX_VALUE / 300; i++) { list.add(i); } long endTime = System.currentTimeMillis(); System.out.println(endTime - beginTime); } }