Spoiler警告です。これはProject Eulerの問題5です。Clojureの性能は、単純なループとJavaの比較では非常に悪いです。
Clojureを学習しようとしていますが、問題5を解決しようとしていますが、ClojureではJavaでは1515 ms対169932 msです。私はタイプヒント、チェックされていない数学演算、およびすべての関数をインライン化することを試みました。
なぜ私のClojureコードはそれほど遅くなっていますか?
Clojureのコード:
(set! *unchecked-math* true)
(defn divides? [^long number ^long divisor] (zero? (mod number divisor)))
(defn has-all-divisors [divisors ^long num]
(if (every? (fn [i] (divides? num i)) divisors) num false))
(time (prn (some (fn [^long i] (has-all-divisors (range 2 20) i)) (iterate inc 1))))
Javaコード:
public class Problem5 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int i = 1;
while(!hasAllDivisors(i, 2, 20)) {
i++;
}
long end = System.currentTimeMillis();
System.out.println(i);
System.out.println("Elapsed time " + (end - start));
}
public static boolean hasAllDivisors(int num, int startDivisor, int stopDivisor) {
for(int divisor=startDivisor; divisor<=stopDivisor; divisor++) {
if(!divides(num, divisor)) return false;
}
return true;
}
public static boolean divides(int num, int divisor) {
return num % divisor == 0;
}
}
Javaコードは2〜18になりますが、Clojureコードは2〜20になります。 – Ankur
申し訳ありませんが、私はそれを修正しました。私は誤ったバージョンのコードを間違って貼り付けていましたが、両方のタイミングが正確に20になるようになっていました。 – gleenn
System.currentTimeMillis()をベンチマークとしますか?これは深刻ではない。 http://shipilev.net/talks/devoxx-Nov2013-benchmarking.pdf – Puh