Permalink
Browse files

across the board standardised way of running mulitple iterations and …

…java performance enhancements suggested by isaac
  • Loading branch information...
1 parent cfedf41 commit 0bace317ef63ec407d91ad2d30abb6e58b9f28bb @dnene dnene committed Aug 20, 2011
View
@@ -1,88 +1,111 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+import java.util.ListIterator;
public class Chain {
- private int count;
- private int nth;
- public Chain(int count, int nth) {
- this.count = count;
- this.nth = nth;
- }
-
- public int shout() {
- List<Integer> people = new ArrayList<Integer>();
- for (int i = 0 ; i < this.count ; i++) {
- people.add(i+1);
- }
- int counter = 0;
- while(people.size() > 1) {
- List<Integer> newPeople = new ArrayList<Integer>();
- for(int i = 0 ; i < people.size() ; i++) {
- if ((counter + i) % this.nth != 0) {
- newPeople.add(people.get(i));
- }
- }
- counter = ((counter + people.size()) % this.nth);
- people = newPeople;
- }
- return people.get(0);
- }
-
- public int shoutRecursive() {
- List<Integer> people = new LinkedList<Integer>();
- for (int i = 0 ; i < this.count ; i++) {
- people.add(i+1);
- }
- return shoutRecursive(people, new LinkedList<Integer>(), this.nth, 0);
- }
-
- public int shoutRecursive(List<Integer> people, List<Integer> survivors, int nth, int counter) {
- if ((survivors.size() == 0) && (people.size() == 1)) {
- return people.get(0);
- } else if (people.size() == 0){
- return shoutRecursive(survivors, new LinkedList<Integer>(), nth, counter);
- } else {
- int v = people.remove(0);
- if (counter != 0) {
- survivors.add(v);
- }
- if (counter == nth - 1) counter = 0;
- else counter = counter + 1;
- return shoutRecursive(people, survivors, nth, counter);
- }
- }
-
- public static void main(String[] args) {
- Chain chain = new Chain(40,3);
- System.out.println(chain.shoutRecursive());
- int ITER = 1000000;
- for (int i = 0 ; i < ITER ; i++)
- {
- chain.shoutRecursive();
- }
- long start = System.nanoTime();
- for (int i = 0 ; i < ITER ; i++)
+
+ private static int[] soldiers(int n)
+ {
+ int[] a = new int[n];
+ for (int i = 0 ; i < a.length ; i++) a[i] = i+1;
+ return a;
+ }
+
+ public static int countoffSoldiersReduction(int n, int kth)
+ {
+ int[] s = soldiers(n);
+ int[] survivors = new int[n];
+ int[] swap;
+ int k = 0, count = n;
+
+ while (count > 1) {
+ int m = 0;
+
+ for (int i = 0 ; i < count; i++)
+ if (i != k) {
+ survivors[m++] = s[i];
+
+ } else {
+ k += kth;
+ }
+
+ k -= count; // wrap around
+
+ swap = s; s = survivors; survivors = swap;
+ count = m;
+ }
+
+ return s[0];
+ }
+ public static int countoffSoldiersRecursion(int n, int kth)
+ {
+ LinkedList<Integer> soldiers = new LinkedList<Integer>();
+ for (int i = 0; i < n; i++) soldiers.add( new Integer(i+1) );
+
+ return countoff( soldiers.listIterator(0), soldiers, kth, kth );
+ }
+
+
+ private static int countoff(
+ ListIterator<Integer> ring, LinkedList<Integer> reset, int kth, int k )
+ {
+ if (ring.hasNext())
{
- chain.shoutRecursive();
+ ring.next();
+
+ if (k != kth) {
+ return countoff(ring, reset, kth, ++k);
+
+ } else {
+ ring.remove();
+ return countoff(ring, reset, kth, 1);
+ }
+
+ } else {
+
+ if (ring.nextIndex() > 1)
+
+ // the only way to reset an iterator is to create a new one from the list
+ return countoff(reset.listIterator(0), reset, kth, k);
+
+ else
+ return ring.previous().intValue();
}
- long end = System.nanoTime();
- System.out.println("Time per iteration (element recursive) = " + ((end - start) / (ITER )) + " nanoseconds.");
+ }
- System.out.println(chain.shout());
-
- for (int i = 0 ; i < ITER ; i++)
- {
- chain.shout();
+ public static void runIterationsReduction(int iterations, int times) {
+ for(int t = 0 ; t < times; t++) {
+ System.gc();
+ long start = System.nanoTime();
+ for(int i = 0; i < iterations ; i++) {
+ countoffSoldiersReduction(40,3);
+ }
+ long end = System.nanoTime();
+ System.out.println(((end - start) * 1.0)/ (iterations * 1000 ));
}
- start = System.nanoTime();
- for (int i = 0 ; i < ITER ; i++)
- {
- chain.shout();
+ }
+
+ public static void runIterationsRecursive(int iterations, int times) {
+ for(int t = 0 ; t < times; t++) {
+ System.gc();
+ long start = System.nanoTime();
+ for(int i = 0; i < iterations ; i++) {
+ countoffSoldiersRecursion(40,3);
+ }
+ long end = System.nanoTime();
+ System.out.println(((end - start) * 1.0)/ (iterations * 1000 ));
}
- end = System.nanoTime();
- System.out.println("Time per iteration (list reduction) = " + ((end - start) / (ITER )) + " nanoseconds.");
-
- }
+ }
+
+ public static void main(String[] args) {
+ int ITER = 1000000;
+ System.out.println("List Reduction");
+ System.out.println(countoffSoldiersReduction(40,3));
+ runIterationsReduction(ITER,10);
+ System.out.println("Element Recursion");
+ System.out.println(countoffSoldiersRecursion(40,3) );
+ runIterationsRecursive(ITER,10);
+ }
}
View
@@ -53,49 +53,35 @@ class Chain(val count: Int) {
object Josephus{
import ExtraControls.loop
- def timeit(tag: String)(f: => Unit): Unit = {
- val iters = 1000000
- var start = System.currentTimeMillis()
- loop(1, iters) { _ =>
- f
- }
- var end = System.currentTimeMillis()
- println((end - start) * 1000.0 / iters + " microseconds ( " + tag + " )")
- }
-
- def warmup(f: => Unit): Unit = {
- loop(1, 100000) { _ =>
- f
+ def runIterations(tag: String, iterations: Int, times: Int)(f: => Unit): Unit = {
+ println("Running " + tag)
+ loop(1, times) { _ =>
+ System.gc();
+ var start = System.nanoTime()
+ loop(1, iterations) { _ => f }
+ var end = System.nanoTime()
+ println(((end - start) * 1.0) / (iterations * 1000))
}
}
def main(args : Array[String]) : Unit = {
+ val ITER = 1000000
val chain = new Chain(40)
println(chain.shout(3))
- warmup {
- val chain = new Chain(40)
- chain.shout(3)
- }
- timeit("oo") {
+ runIterations("oo",ITER,10) {
val chain = new Chain(40)
chain.shout(3)
}
- println(shoutPatternMatch(40, 3))
- warmup {
- shoutPatternMatch(40,3)
- }
- timeit ("element recursive") {
- shoutPatternMatch(40,3)
+ println(shoutRecursive(List.range(1, 41),Nil,3,1))
+ runIterations ("element recursive", ITER,10) {
+ shoutRecursive(List.range(1, 41),Nil,3,1)
}
- println(shoutListProcessing(40,3))
- warmup {
- shoutListProcessing(40,3)
- }
- timeit ("list reduction"){
- shoutListProcessing(40,3)
+ println(shoutListProcessing(ArrayBuffer.range(1, 41),3))
+ runIterations ("list reduction", ITER, 10){
+ shoutListProcessing(ArrayBuffer.range(1, 41),3)
}
}
@@ -114,25 +100,17 @@ object Josephus{
}
people(0)
}
-
- def shoutListProcessing(count: Int, nth: Int): Int = {
- shoutListProcessing(ArrayBuffer.range(1, 41),3)
- }
- def shoutPatternMatch(soldiers : List[Int], survivors: List[Int], n: Int, counter: Int): Int = {
- (soldiers, survivors, n, counter) match {
- case(h :: Nil, Nil, _, _) => h
- case(Nil, s, _, _) => shoutPatternMatch(s reverse, Nil, n, counter)
- case(h :: t, s, n, 1) =>
- shoutPatternMatch(t, s, n, 2)
- case(h :: t, s, n, c) =>
- shoutPatternMatch(t, h :: s, n, if(c == n) 1 else c + 1)
+ @scala.annotation.tailrec
+ final def shoutRecursive(soldiers : List[Int], survivors: List[Int], n: Int, counter: Int): Int = {
+ if (soldiers.isEmpty) shoutRecursive(survivors.reverse, Nil, n, counter)
+ else {
+ if (soldiers.tail.isEmpty && survivors.isEmpty) soldiers.head
+ else
+ if (counter == 1) shoutRecursive(soldiers.tail, survivors, n, 2)
+ else shoutRecursive(soldiers.tail, soldiers.head :: survivors,
+ n, if (counter == n) 1 else counter + 1)
}
}
-
- def shoutPatternMatch(count: Int, nth: Int): Int = {
- shoutPatternMatch(List.range(1, 41),Nil,3,1)
- }
-
}
@@ -14,13 +14,13 @@
(defn josephus [people nth]
(shout (vec-range 1 (inc people)) nth 0))
-(defn countdown [iterations]
- (dotimes [_ iterations]
- (josephus 40 3)))
+(defn run-iterations [iterations times]
+ (dotimes [_ times]
+ (let [start (System/nanoTime)]
+ (dotimes[_ iterations]
+ (josephus 40 3))
+ (let [end (System/nanoTime)]
+ (println (float (/ (- end start) (* 1000 iterations))))))))
(println (josephus 40 3))
-(countdown 100000)
-(let [start (System/currentTimeMillis) iterations 100000]
- (countdown iterations)
- (let [end (System/currentTimeMillis)]
- (println (/ (* (- end start) 1000.00) iterations) " microseconds")))
+(run-iterations 1000000 10)
@@ -9,7 +9,7 @@ shout([Head | []], [], _, _) -> Head;
shout([], Survivors, Nth, Counter) ->
%% io:format("Reversing~n",[]),
shout(lists:reverse(Survivors),[], Nth, Counter);
-shout([Head | Tail], Survivors, Nth, 1) ->
+shout([_ | Tail], Survivors, Nth, 1) ->
%% io:format("~w dies~n",[Head]),
shout(Tail, Survivors, Nth, 2);
shout([Head | Tail], Survivors, Nth, Nth) ->
@@ -19,16 +19,20 @@ shout([Head | Tail], Survivors, Nth, Counter) ->
%% io:format("~w survives~n",[Head]),
shout(Tail, [Head | Survivors], Nth, Counter + 1).
-iter(0) -> ok;
-iter(N) ->
- Result = shout(40,3),
- %% io:format("~w ~w~n",[N,Result]),
- iter(N-1).
+run_iterations(0) -> ok;
+run_iterations(Iterations) ->
+ shout(40,3),
+ run_iterations(Iterations - 1).
-benchmark() ->
- Iter = 1000000,
- iter(Iter),
+run_times(_,0) -> ok;
+run_times(Iterations, Times) ->
Start = os:timestamp(),
- iter(Iter),
+ run_iterations(Iterations),
End = os:timestamp(),
- io:format("Time is ~w microseconds per iteration (element recursive)~n",[timer:now_diff(End,Start) / Iter]).
+ io:format("~w~n",[timer:now_diff(End,Start) / Iterations]),
+ run_times(Iterations,Times-1).
+
+benchmark() ->
+ Iter = 1000000,
+ io:format("(element recursive)~n",[]),
+ run_times(Iter,10).
@@ -26,12 +26,15 @@ def find_last(people,acc,nth,count) {
}
}
+def runIterations(iterations, times) {
+ for(i = 0 ; i < times ; i++) {
+ def start = System.nanoTime()
+ for(def j = 0 ; j < iterations ; j++)
+ find_last()
+ def end = System.nanoTime()
+ println ((end - start)/(iterations * 1000))
+ }
+}
+
println find_last()
-def ITER = 100000
-for(def i = 0 ; i < ITER ; i++)
- find_last()
-def start = System.nanoTime()
-for(def i = 0 ; i < ITER ; i++)
- find_last()
-def end = System.nanoTime()
-println "Time per iteration = " + ((end - start)/(ITER * 1000)) + " microseconds"
+runIterations(1000000,10)
Oops, something went wrong.

0 comments on commit 0bace31

Please sign in to comment.