package com.googlecode.totallylazy.functions; import com.googlecode.totallylazy.Sequence; import com.googlecode.totallylazy.numbers.Numbers; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import static com.googlecode.totallylazy.Sequences.iterate; import static com.googlecode.totallylazy.Sequences.repeat; import static com.googlecode.totallylazy.Sequences.sequence; import static com.googlecode.totallylazy.numbers.Numbers.add; import static com.googlecode.totallylazy.numbers.Numbers.ascending; import static com.googlecode.totallylazy.numbers.Numbers.descending; import static com.googlecode.totallylazy.numbers.Numbers.multiply; public class TimeReport implements Block<Number> { private final List<Number> times = new ArrayList<Number>(); @Override public void execute(Number time) throws Exception { this.times.add(time); } public double lastTime() { return times.get(times.size() - 1).doubleValue(); } public void reset() { times.clear(); } @Override public String toString() { return String.format("Elapsed msecs for %s runs:\tAvg:%.5f\tMin:%.5f\tMax:%.5f\tTotal:%.5f", runs(), average(), minimum(), maximum(), total()); } public double minimum() { return sequence(times).sortBy(ascending()).head().doubleValue(); } public double maximum() { return sequence(times).sortBy(descending()).head().doubleValue(); } public double average() { return sequence(times). sortBy(ascending()). drop(tenPercent()). reverse(). drop(tenPercent()). reduce(Numbers.average()). doubleValue(); } private int tenPercent() { return (int) Math.floor(times.size() * 0.10); } public int runs() { return times.size(); } public double total() { return sequence(times).reduce(add()).doubleValue(); } public static TimeReport time(int numberOfCalls, Sequence<?> sequence) { TimeReport report = new TimeReport(); repeat(Time0.time(sequence, report)).take(numberOfCalls).realise(); return report; } public static TimeReport time(int numberOfCalls, Callable<?> callable) { TimeReport report = new TimeReport(); repeat(Time0.time(callable, report)).take(numberOfCalls).realise(); return report; } public static void timeRatio(final Callable<?> function) { iterate(multiply(2), 125).map(time(function)).reduce(new CurriedBinary<TimeReport>() { @Override public TimeReport call(TimeReport previous, TimeReport current) throws Exception { Number ratio = Numbers.divide(current.average(), previous.average()); System.out.println("Ratio:" + ratio + " " + current); return current; } }); } private static Function1<Number, TimeReport> time(final Callable<?> function) { return number -> time(number.intValue(), function); } }