Feragatname
Yapay kriterlerin kötü olduğunu biliyorum. Yalnızca çok özel dar durum için sonuçlar gösterebilirler. Aptal bir sıra yüzünden bir dilin diğerinden daha iyi olduğunu düşünmüyorum. Ancak sonuçların neden bu kadar farklı olduğunu merak ediyorum. Lütfen alttaki sorularıma bakın.
Matematik karşılaştırma açıklaması
Kıyaslama, 6 farklı asal sayı çiftlerini bulmaya yönelik basit matematik hesaplamalarıdır (sözde seksi asal sayılar ). Örneğin, 100'ün altındaki seksi asal sayılar şöyle olacaktır:(5 11) (7 13) (11 17) (13 19) (17 23) (23 29) (31 37) (37 43) (41 47) (47 53) (53 59) (61 67) (67 73) (73 79) (83 89) (97 103)
Sonuçlar tablosu
Tabloda: saniye cinsinden hesaplama süresi Çalışıyor: Factor hariç tümü VirtualBox'ta çalışıyordu (Debian kararsız amd64 konuğu, Windows 7 x64 ana bilgisayar) CPU: AMD A4-3305M
Sexy primes up to: 10k 20k 30k 100k
Bash 58.00 200.00 [*1] [*1]
C 0.20 0.65 1.42 15.00
Clojure1.4 4.12 8.32 16.00 137.93
Clojure1.4 (optimized) 0.95 1.82 2.30 16.00
Factor n/a n/a 15.00 180.00
Python2.7 1.49 5.20 11.00 119
Ruby1.8 5.10 18.32 40.48 377.00
Ruby1.9.3 1.36 5.73 10.48 106.00
Scala2.9.2 0.93 1.41 2.73 20.84
Scala2.9.2 (optimized) 0.32 0.79 1.46 12.01
[* 1] - Ne kadar zaman alacağını hayal etmekten korkuyorum
Kod listeleri
C:
int isprime(int x) {
int i;
for (i = 2; i < x; ++i)
if (x%i == 0) return 0;
return 1;
}
void findprimes(int m) {
int i;
for ( i = 11; i < m; ++i)
if (isprime(i) && isprime(i-6))
printf("%d %d\n", i-6, i);
}
main() {
findprimes(10*1000);
}
Yakut:
def is_prime?(n)
(2...n).all?{|m| n%m != 0 }
end
def sexy_primes(x)
(9..x).map do |i|
[i-6, i]
end.select do |j|
j.all?{|j| is_prime? j}
end
end
a = Time.now
p sexy_primes(10*1000)
b = Time.now
puts "#{(b-a)*1000} mils"
Scala:
def isPrime(n: Int) =
(2 until n) forall { n % _ != 0 }
def sexyPrimes(n: Int) =
(11 to n) map { i => List(i-6, i) } filter { _ forall(isPrime(_)) }
val a = System.currentTimeMillis()
println(sexyPrimes(100*1000))
val b = System.currentTimeMillis()
println((b-a).toString + " mils")
Scala optimize edildi isPrime
(Clojure optimizasyonundaki ile aynı fikir):
import scala.annotation.tailrec
@tailrec // Not required, but will warn if optimization doesn't work
def isPrime(n: Int, i: Int = 2): Boolean =
if (i == n) true
else if (n % i != 0) isPrime(n, i + 1)
else false
Clojure:
(defn is-prime? [n]
(every? #(> (mod n %) 0)
(range 2 n)))
(defn sexy-primes [m]
(for [x (range 11 (inc m))
:let [z (list (- x 6) x)]
:when (every? #(is-prime? %) z)]
z))
(let [a (System/currentTimeMillis)]
(println (sexy-primes (* 10 1000)))
(let [b (System/currentTimeMillis)]
(println (- b a) "mils")))
Clojure optimize edildi is-prime?
:
(defn ^:static is-prime? [^long n]
(loop [i (long 2)]
(if (= (rem n i) 0)
false
(if (>= (inc i) n) true (recur (inc i))))))
Python
import time as time_
def is_prime(n):
return all((n%j > 0) for j in xrange(2, n))
def primes_below(x):
return [[j-6, j] for j in xrange(9, x+1) if is_prime(j) and is_prime(j-6)]
a = int(round(time_.time() * 1000))
print(primes_below(10*1000))
b = int(round(time_.time() * 1000))
print(str((b-a)) + " mils")
Faktör
MEMO:: prime? ( n -- ? )
n 1 - 2 [a,b] [ n swap mod 0 > ] all? ;
MEMO: sexyprimes ( n n -- r r )
[a,b] [ prime? ] filter [ 6 + ] map [ prime? ] filter dup [ 6 - ] map ;
5 10 1000 * sexyprimes . .
Bash (zsh):
#!/usr/bin/zsh
function prime {
for (( i = 2; i < $1; i++ )); do
if [[ $[$1%i] == 0 ]]; then
echo 1
exit
fi
done
echo 0
}
function sexy-primes {
for (( i = 9; i <= $1; i++ )); do
j=$[i-6]
if [[ $(prime $i) == 0 && $(prime $j) == 0 ]]; then
echo $j $i
fi
done
}
sexy-primes 10000
Sorular
- Scala neden bu kadar hızlı? Statik yazım yüzünden mi? Yoksa JVM'yi çok verimli bir şekilde mi kullanıyor?
Ruby ve Python arasında neden bu kadar büyük bir fark var? Bu ikisinin tamamen farklı olmadığını düşündüm. Belki kodum yanlıştır. Lütfen beni aydınlat! Teşekkürler.UPD Evet, kodumda hata vardı. Python ve Ruby 1.9 oldukça eşittir.- Ruby sürümleri arasında verimlilikte gerçekten etkileyici sıçrama.
- Clojure kodunu tür bildirimleri ekleyerek optimize edebilir miyim? Yardımcı olacak mı?
sqrt(n)
ama bunun hesaplanması biraz zaman alabilir. Ayrıca, C kodunuz bulduğu asal sayıları basarken, diğer dilleriniz bunları listeler halinde hesaplar ve ardından yazdırır. C şaşırtıcı olmayan bir şekilde en hızlısı olsa da, daha hızlı elde edebilirsiniz.