Khước từ
Tôi biết rằng điểm chuẩn nhân tạo là xấu. Chúng chỉ có thể hiển thị kết quả cho các tình huống hẹp rất cụ thể. Tôi không cho rằng ngôn ngữ này tốt hơn ngôn ngữ kia vì một số thứ ngu ngốc. Tuy nhiên tôi tự hỏi tại sao kết quả lại khác nhau như vậy. Vui lòng xem câu hỏi của tôi ở phía dưới.
Mô tả điểm chuẩn toán học
Điểm chuẩn là các phép tính toán học đơn giản để tìm các cặp số nguyên tố khác nhau bằng 6 (gọi là số nguyên tố sexy ) Ví dụ: các số nguyên tố sexy dưới 100 sẽ là:(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)
Bảng kết quả
Trong bảng: thời gian tính bằng giây Đang chạy: tất cả ngoại trừ Factor đang chạy trong VirtualBox (máy khách amd64 không ổn định Debian, máy chủ Windows 7 x64) 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] - Tôi sợ tưởng tượng sẽ mất bao nhiêu thời gian
Danh sách mã
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);
}
Ruby:
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 đã isPrime
tối ưu hóa (ý tưởng tương tự như trong tối ưu hóa Clojure):
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 được tối ưu hóa 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")
Hệ số
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
Câu hỏi
- Tại sao Scala lại nhanh như vậy? Có phải vì gõ tĩnh không? Hay nó chỉ đang sử dụng JVM rất hiệu quả?
Tại sao lại có sự khác biệt lớn giữa Ruby và Python? Tôi nghĩ hai cái này không hoàn toàn khác nhau. Có lẽ mã của tôi là sai. Vui lòng làm sáng tỏ cho tôi! Cảm ơn.UPD Có, đó là lỗi trong mã của tôi. Python và Ruby 1.9 khá ngang nhau.- Sự nhảy vọt thực sự ấn tượng về năng suất giữa các phiên bản Ruby.
- Tôi có thể tối ưu hóa mã Clojure bằng cách thêm khai báo kiểu không? Nó sẽ giúp?
sqrt(n)
nhưng có thể mất một chút thời gian để tính toán. Ngoài ra, mã C của bạn in ra các số nguyên tố khi nó tìm thấy chúng, trong khi các ngôn ngữ khác của bạn tính toán chúng thành danh sách và sau đó in chúng ra. Mặc dù C nhanh nhất không có gì đáng ngạc nhiên, nhưng bạn có thể có được nó nhanh hơn.