अस्वीकरण
मुझे पता है कि कृत्रिम बेंचमार्क बुराई हैं। वे केवल बहुत विशिष्ट संकीर्ण स्थिति के लिए परिणाम दिखा सकते हैं। मैं यह नहीं मानता कि कुछ बेवकूफ बेंच के कारण एक भाषा दूसरे से बेहतर है। हालांकि मुझे आश्चर्य है कि परिणाम इतने अलग क्यों हैं। कृपया मेरे प्रश्नों को नीचे देखें।
गणित बेंचमार्क विवरण
बेंचमार्क सरल गणित की गणना है, जो कि अभाज्य संख्याओं की जोड़ियों को खोजने के लिए है, जो 6 से भिन्न होती है (जिसे सेक्सी प्राइम कहा जाता है ) जैसे कि 100 से कम सेक्सी प्राइम निम्न होंगे:(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)
परिणाम तालिका
तालिका में: सेकंड में गणना समय चल रहा है: सभी को छोड़कर फैक्टर वर्चुअलबॉक्स में चल रहा था (डेबियन अस्थिर amd64 अतिथि, विंडोज 7 x 64 होस्ट) 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] - मैं कल्पना करने से डरता हूं कि इसमें कितना समय लगेगा
कोड लिस्टिंग
सी:
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);
}
माणिक:
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"
स्काला:
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")
स्काला ने opimized isPrime
( क्लोजर ऑप्टिमाइज़ेशन में समान विचार):
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")))
क्लोजर अनुकूलित 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))))))
अजगर
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")
फ़ैक्टर
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 . .
बैश (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
प्रशन
- स्काला इतना तेज क्यों है? क्या यह स्थैतिक टाइपिंग के कारण है ? या यह सिर्फ जेवीएम का बहुत कुशलता से उपयोग कर रहा है?
रूबी और पायथन के बीच इतना बड़ा अंतर क्यों? मुझे लगा कि ये दोनों कुछ अलग नहीं हैं। शायद मेरा कोड गलत है। कृपया मुझे ज्ञान दो! धन्यवाद।UPD हाँ, यह मेरे कोड में त्रुटि थी। पायथन और रूबी 1.9 बहुत समान हैं।- रूबी संस्करणों के बीच उत्पादकता में वास्तव में प्रभावशाली छलांग।
- क्या मैं प्रकार की घोषणाओं को जोड़कर क्लोजर कोड का अनुकूलन कर सकता हूं? क्या यह मदद करेगा?
C: 2.723s
Go: 2.743s
:।
sqrt
इस चेक के लिए गणना करने की आवश्यकता नहीं है । आप के i
रूप में के वर्ग की गणना कर सकते हैंfor (i = 2; i * i <= x; ++i) ...
isPrime
साथ एनोटेट @tailrec
करें, यह सुनिश्चित करने के लिए कि आप पूंछ पुनरावृत्ति का उपयोग कर रहे हैं। गलत तरीके से कुछ करना आसान है जो पूंछ पुनरावृत्ति को रोकता है, और यह एनोटेशन आपको चेतावनी देता है कि यदि ऐसा होता है।
sqrt(n)
लेकिन यह गणना करने के लिए कुछ समय ले सकता है। साथ ही आपका सी कोड उन प्रिंटों को प्रिंट करता है जैसा कि वह उन्हें पाता है, जबकि आपकी अन्य भाषाएं उन्हें सूचियों में गणना करती हैं और फिर उन्हें प्रिंट करती हैं। जबकि सी सबसे तेजी से है, आप इसे तेजी से प्राप्त करने में सक्षम हो सकते हैं।