これは、Clojureに本当に精通している人々への質問になります。
JavaとClojureで簡単な素数チェック関数を書いて、実行時間を比較したかったのです。
これがJavaの私のコードです:
import java.util.LinkedList;
public class Primes {
public static void main(String args[])
{
long start = System.nanoTime();
getPrimes(10000);
long end = System.nanoTime();
System.out.println(((float)(end - start)/1000000) + "ms");
}
private static LinkedList<Integer> getPrimes(int n)
{
int count = 0;
int current = 1;
LinkedList<Integer> primes = new LinkedList<Integer>();
while(count <= n)
{
if(isPrime(current))
{
primes.add(current);
count++;
}
current++;
}
return primes;
}
private static boolean isPrime(long n)
{
if(n <= 0) return false;
if(n == 1 || n == 2) return true;
if(n % 2 == 0) return false;
for(int i=3; i<Math.sqrt(n) + 1; i=i+2)
{
if(n % i == 0){
return false;
}
}
return true;
}
}
そして、これがClojureに相当するものです:
(defn prime? [n]
(or (= n 2) (not (some #(zero? (rem n %)) (conj (range 3 (inc (Math/sqrt n)) 2) 2)))))
(defn printPrimes [n] (take n (filter prime? (iterate inc 1))))
(defn ExecTime [function & arguments] (let [start (System/nanoTime), return (dorun (apply function arguments)), end (System/nanoTime)] (/ (- end start) 1000000.0)))
(ExecTime printPrimes 10000)
今、私が確信していないことがいくつかあります:
- (let)とバインディングの開始時間と終了時間は、Clojureでの実行時間を測定するのに問題ありませんか?
- 何らかの理由で(JavaバージョンとClojureバージョンは同じアルゴリズムを使用していますが)、Clojureバージョンははるかに低速です(J:〜50ms、C:〜400ms)。私は何か間違ったことをしていますか?
明らかな間違いを犯した場合は失礼しますが、Clojureの学習段階にあります...
- - -編集 - - -
私はそれを最適化し、最終的にはJavaと同じ時間を達成しました。興味のある人のためにブログで説明しています:http:
//blog.programmingdan.com/ ?p = 35