I'm back with an optimization question. Lately I've been dealing with some huge volume of data and I've realized how performance can start to be a serious problem as the data increases. Here is a small illustration with relatively less data (50,000 values). Hopefully the question should be self explanatory from the code.
package com.test;
import java.util.List;
import java.util.ArrayList;
class MyCollection{
public static void populateList(List<Long> l, int multiple){
for(int i=0; i<50000; i++){
Long value = Long.valueOf(i*multiple);
l.add(value);
}
}
public static void main(String[] args) {
List<Long> listOf2 = new ArrayList<Long>();
populateList(listOf2, 2);
List<Long> listOf3 = new ArrayList<Long>();
populateList(listOf3, 3);
long startTimestamp, endTimestamp;
List<Long> commonA = null, commonB = null, commonC = null;
//First Attempt - Runs in 60 seconds
startTimestamp = System.currentTimeMillis();
commonA = new ArrayList<Long>(listOf2);
commonA.retainAll(listOf3);
endTimestamp = System.currentTimeMillis();
System.out.println("Execution Time : " + (endTimestamp-startTimestamp)/1000);
//Second Attempt - Runs in 73 seconds -
//There are fewer elements in commonB shouldn't this run faster?
startTimestamp = System.currentTimeMillis();
commonB = new ArrayList<Long>(listOf3);
commonB.retainAll(listOf2);
endTimestamp = System.currentTimeMillis();
System.out.println("Execution Time : " + (endTimestamp-startTimestamp)/1000);
System.out.println("Are Equal : " + (commonA.equals(commonB)));
//Third Attempt - Runs in 2 seconds
startTimestamp = System.currentTimeMillis();
/* This part has been intentionally left blank.
* That is because I need to have a question for the puzzle,
* and I felt like leaving out the Third part would be the right
* thing do to.
* I've done most of the hard work so this should be easy to fill.
* Yes this must run 10 times faster than the solution I have provided
* and should be done just as many lines (3 to 5 lines of code should be fine!).
* Well I never said anything about life being fair, did I?
* */
endTimestamp = System.currentTimeMillis();
System.out.println("Execution Time : " + (endTimestamp-startTimestamp)/1000);
System.out.println("Are Equal : " + (commonA.equals(commonC)));
}
}
Just keep in mind that both the "Are Equal" print statements print true and that you don't use the reference commonA or commonB when writing the code for the third part. You are free to make any other changes (in the place where the comments are there).
Update - The commonA, commonB were incorrectly pointing to the objects listOf2/listof3. That has been corrected to create new Objects -- it now reads commonA = new ArrayList
(listOf2); instead of commonA = listOf2;.
Thanks to Colin Hebert for pointing it out.