Java – what slows down this clojure feature?

I work in clojure project Euler problem 14 I have a good general algorithm and I get the correct results, but it is difficult for me to understand why my function is so slow compared with the equivalent function in Java This is my clojure function, which is used to obtain the length of Collatz chain from the given starting number:

(defn collatz-length
  [n]
  (loop [x n acc 1]
    (if (= 1 x)
      acc
      (recur (if (even? x)
               (/ x 2)
               (inc (* 3 x)))
             (inc acc)))))

This is my java function that does the same thing:

public static int collatzLength(long x) {
    int count = 0;
    while (x > 1) {
        if ((x % 2) == 0) {
            x = x / 2;
        } else {
            x = (x * 3) + 1;
        }
        count++;
    }
    return count;
}

To calculate the performance of these functions, I used the following clojure Code:

(time (dorun (map collatz-length (range 1 1000000))))

The following java code:

long starttime = System.currentTimeMillis();

int[] nums = new int[1000000];
for (int i = 0; i < 1000000; i++) {
    nums[i] = collatzLength(i+1);
}

System.out.println("Total time (ms) : " + (System.currentTimeMillis() - starttime));

Java code runs 304 milliseconds on my machine, but clojure code takes 4220 milliseconds What causes this bottleneck and how can I improve the performance of clojure code?

Solution

You are using boxed math, so numbers will continue to be boxed and unboxed Try something similar:

(set! *unchecked-math* true)
(defn collatz-length
  ^long [^long n]
  (loop [x n acc 1]
    (if (= 1 x)
      acc
      (recur (if (zero? (rem x 2))
               (quot x 2)
               (inc (* 3 x)))
             (inc acc)))))
 (time (dorun (loop [i 1] (when (< i 1000000) (collatz-length i) (recur (inc i))))))
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>