Consider the following Java code (complete, compiles and runs fine).
The code creates an array containing 5,000,000 integers (from 1 to 5 million), iterates over it and creates an ArrayList from the perfect squares it finds. Ideal squares are detected using the naive method, not bit manipulation, but this does not apply to the problem.
Mathematically, between 1 and 5 M, there are 2236 perfect squares. Thus, the ArrayList array, in which ideal squares are placed, will have a final size of 2236.
import java.util.ArrayList; public class PerfSquares { public static ArrayList<Integer> perfectSquares(int[] arr) { ArrayList<Integer> al = new ArrayList<Integer>(); // ArrayList<Integer> al = new ArrayList<Integer>(arr.length); for (int i = 0; i < arr.length; i++) { double root = Math.sqrt(arr[i]); int irt = (int) Math.floor(root); if (irt * irt == arr[i]) { al.add(arr[i]); } } return al; } public static void main(String[] args) { int[] arr = new int[5000000]; for (int i = 0; i < arr.length; i++) { arr[i] = i + 1; } long s = System.currentTimeMillis(); perfectSquares(arr); long e = System.currentTimeMillis(); System.out.println(e - s); } }
I would like to focus on declaring an ArrayList. These two lines, one of which is commented out:
ArrayList<Integer> al = new ArrayList<Integer>(); //ArrayList<Integer> al = new ArrayList<Integer>(arr.length);
When I run with the first declaration ( without the size explicitly specified), I see the timediff:
~96 milliseconds.
When I run with the second declaration ( with the size explicitly provided), the timediff increases to:
~105 milliseconds
Question:
Why is this so? Should the second case (size supplied) be faster?
According to my understanding, in the first case, when we omit the size parameter in ArrayList, an array of length 10 will be initialized backstage. And when this bandwidth is exceeded, a new array with a larger capacity (not sure how much more) will be allocated, and previous items will be copied.
For 2236 elements and without an initial size, this cycle is "exceeded - assign a new one - copy over - add more until the cap" cycle should be repeated many times, slowing it down.
Therefore, I expected the ad provided by the size to be faster. Since the distribution will happen once, and there will be no way to exceed / create and copy new arrays.
Or is this basically the case, because 2236 joins an ArrayList, even with all cycles exceeding the number of copies, will still be faster than creating an ArrayList of size 5,000,000?