Hi, I believe I've heard claims that nothing stops Clojure 1.3 code to be made very close to Java in terms of execution speed.
However when trying to match the speed of ad-hoc Heapsort implementation I have faced essential obstacles. Setting type hints and coercions was quite easy. A bit harder was to realize that "aset" is much faster than "aset-int" and that "(int -1)" inside "if" condition can be faster than "-1". However I'm still far from the Java speed ( 1.5 times slower on a cut code - first part of the Heapsort ). What I can't understand now is why inlining the following function makes a noticeable speedup (~20%). Isn't it supposed to be solved in 1.3? (defn move-up! [^long pos] (let [array (ints array)] (loop [pos pos ppos (unchecked-divide-int pos 2)] (if (or (= pos 0) (>= (aget array ppos) (aget array pos))) nil (do ;(swap! array ppos pos) (recur ppos (unchecked-divide-int ppos 2))))))) I'm attaching the full sources if anyone is interested to measure the difference. Regards, Sergey. P.S. java version "1.7.0_02" Java(TM) SE Runtime Environment (build 1.7.0_02-b13) Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
public class _myc { static class HeapSort { final static int Mu = 1235523; final static int Mo = 2012345678; //~ final static int ASIZE = 100000; final static int ASIZE = 100000; //~ final static int ASIZE = 12; private static int[] a = new int[ASIZE]; public static void initArray(int first) { first++; for (int i = 0; i < ASIZE; ++i) { a[i] = first; first = (first * Mu) % Mo; } } public static void printArray() { for (int i = 0; i < ASIZE; ++i) System.out.println(a[i]); } public static void heapSort() { for (int i = 1; i < ASIZE; ++i) { move_up(i); } // TEMP: commented out //~ for (int i = ASIZE - 1; i >=1; --i) { //~ swap_a(0, i); //~ move_down(i); //~ } } static void swap_a(int pos1, int pos2) { int tmp = a[pos1]; a[pos1] = a[pos2]; a[pos2] = tmp; } // keep larger numbers first static void move_up(int pos) { int ppos = pos / 2; while (pos > 0 && a[ppos] < a[pos]) { // TEMP: commented out //~ swap_a(ppos, pos); pos = ppos; ppos = pos / 2; } } // keep larger numbers first static void move_down(int cur_size) { int ppos = 0; int pos; do { pos = ppos * 2; if (pos >= cur_size) { pos = -1; } else if (pos + 1 < cur_size) { if (a[pos+1] > a[pos]) { pos = pos + 1; } } if (pos > -1 && a[ppos] < a[pos]) { swap_a(ppos, pos); ppos = pos; } else { break; } } while (true); } } //~ static private final Runtime RUNTIME = Runtime.getRuntime(); //~ static long mb = 1024l; public static void main(String[] args) { long start = System.currentTimeMillis(); for (int i = 0; i < 200; ++i) { //~ for (int i = 0; i < 1; ++i) { HeapSort.initArray(i); HeapSort.heapSort(); //~ System.out.println("Free: " + RUNTIME.freeMemory() / mb + //~ ", total: " + RUNTIME.totalMemory() / mb + //~ " , max: " + RUNTIME.maxMemory() / mb ); } //~ HeapSort.printArray(); long end = System.currentTimeMillis(); System.out.println("Execution time: "+(end-start)+" ms."); } }
heapsort.clj
Description: Binary data