package org.adoptajsr.runners;

import au.com.bytecode.opencsv.CSVReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.adoptajsr.java8.Java8Recommender;
import org.adoptajsr.runners.Purchases.Purchase;

public abstract class Recommender {
    
    public static void main (String[] args) {
        Purchases purchases = loadPurchases();
        final int maxProductId = purchases.getMaxProductId();
        Random random = new Random();
        List<Integer> others = new ArrayList<>();
        Arrays.asList(new Java8Recommender()).forEach(recommender -> {
            recommender.inject(purchases);
            for (int i = 0; i < 100; i++) {
                long time = System.currentTimeMillis();
                recommender.preprocess();
                for (int j = 0; j < maxProductId; j += 2) {
                    List<Integer> recommendations = recommender.alsoBought(j, i);
                    
                    // Avoid being DCE'd
                    if (random.nextDouble() < 0.01)
                        others.addAll(recommendations);
                }
                System.out.println(System.currentTimeMillis() - time);
            }
        });
    }

    private static Purchases loadPurchases() {
        String file = Recommender.class.getResource("datafile").getFile();
        Purchases coincidences = new Purchases();
        try (CSVReader reader = new CSVReader(new FileReader(file))) {
            while (true) {
                String[] line = reader.readNext();
                if (line == null)
                    return coincidences;
                
                int userId = Integer.parseInt(line[0].trim());
                int productId = Integer.parseInt(line[1].trim());
                coincidences.addPurchase(new Purchase(userId, productId));
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    public abstract List<Integer> alsoBought(int item, int number);

    public abstract void inject(Purchases coincidences);

    public abstract void preprocess();

}

@@ -750,17 +750,16 @@
 ; i %3C 10
-0
 ; i++) %7B
@@ -1207,27 +1207,25 @@
     
-System.out.println(
+long timeTaken = 
 Syst
@@ -1253,16 +1253,106 @@
 ) - time
+;%0A                System.out.println(%22TIME : %22 + timeTaken);%0A                others.clear(
 );%0A     

make times a bit more consistent by keeping the list size constant