Это будет вопрос для людей, действительно знакомых с Clojure.
Я хотел написать простую функцию проверки простых чисел в Java и Clojure, а также сравнить время выполнения.
Так вот мой код в Java:Генерация временных рядов в Clojure
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)
В настоящее время существует несколько вещей, которые я не уверен:
- ли (пусть) и обязательное время начала и окончания ok для измерения времени выполнения в Clojure?
- По какой-то причине (хотя версии Java и Clojure используют тот же алгоритм), версия Clojure намного медленнее (J: ~ 50 мс, C: ~ 400 мс). Я делаю что-то неправильно?
Простите мое невежество, если я сделал некоторые очевидные ошибки, но я до сих пор нахожусь на стадии обучения с Clojure ...
----- EDIT -----
I оптимизировали его и, в конечном итоге, достигли того же уровня, что и Java. Я описываю это в моем блоге для людей, интересующихся:
http://blog.programmingdan.com/?p=35
'if (n == 1 || n == 2) return true;' по обычно используемому определению (ям) 1 не является простым. –
yep Я понял, уже исправил это, спасибо. Проблема в том, что эффективность на 6-8x медленнее, чем тот же алгоритм в Java ... –
Может ли быть, что clojure использует произвольные целые числа по умолчанию? Если это так, использование целых чисел фиксированной ширины, вероятно, даст хорошее ускорение. –