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.");
	}
}

Attachment: heapsort.clj
Description: Binary data

Reply via email to