Đây là phần tiếp theo của Python thực sự chậm như thế nào? (Hoặc ngôn ngữ của bạn nhanh như thế nào?) .
Hóa ra việc tăng tốc độ x100 cho câu hỏi cuối cùng của tôi là quá dễ dàng. Đối với những người thích thử thách nhưng muốn một cái gì đó khó hơn, nơi họ thực sự có thể sử dụng các kỹ năng cấp thấp của mình, đây là phần II. Thách thức là để có được một tốc độ tăng tốc x100 cho mã python sau đây như được thử nghiệm trên máy tính của tôi.
Để làm cho nó khó khăn hơn tôi đang sử dụng pypy lần này. Thời gian hiện tại đối với tôi là 1 phút và 7 giây bằng pypy 2.2.1.
Quy tắc
- Người đầu tiên gửi mã mà tôi có thể chạy, là chính xác và nhanh hơn x100 lần trên máy của tôi sẽ được thưởng 50 điểm.
- Tôi sẽ trao phần thắng cho mã nhanh nhất sau một tuần.
import itertools
import operator
import random
n = 8
m = 8
iters = 1000
# creates an array of 0s with length m
# [0, 0, 0, 0, 0, 0, 0, 0]
leadingzerocounts = [0]*m
# itertools.product creates an array of all possible combinations of the
# args passed to it.
#
# Ex:
# itertools.product("ABCD", "xy") --> Ax Ay Bx By Cx Cy Dx Dy
# itertools.product("AB", repeat=5) --> [
# ('A', 'A', 'A', 'A', 'A'),
# ('A', 'A', 'A', 'A', 'B'),
# ('A', 'A', 'A', 'B', 'A'),
# ('A', 'A', 'A', 'B', 'B'),
# etc.
# ]
for S in itertools.product([-1,1], repeat = n+m-1):
for i in xrange(iters):
F = [random.choice([-1,0,0,1]) for j in xrange(n)]
# if the array is made up of only zeros keep recreating it until
# there is at least one nonzero value.
while not any(F):
F = [random.choice([-1,0,0,1]) for j in xrange(n)]
j = 0
while (j < m and sum(map(operator.mul, F, S[j:j+n])) == 0):
leadingzerocounts[j] +=1
j += 1
print leadingzerocounts
Đầu ra phải tương tự như
[6335185, 2526840, 1041967, 439735, 193391, 87083, 40635, 19694]
Bạn phải sử dụng một hạt giống ngẫu nhiên trong mã của mình và bất kỳ trình tạo số ngẫu nhiên nào đủ tốt để đưa ra câu trả lời gần với ở trên sẽ được chấp nhận.
Máy của tôi Thời gian sẽ được chạy trên máy của tôi. Đây là bản cài đặt Ubuntu tiêu chuẩn trên Bộ xử lý tám lõi AMD FX-8350. Điều này cũng có nghĩa là tôi cần để có thể chạy mã của bạn.
Giải thích mã
Mã này lặp lại trên tất cả các mảng S có độ dài n + m-1 được tạo thành cho -1 và 1 giây. Đối với mỗi mảng S, nó lấy mẫu 1000 mảng ngẫu nhiên khác không F có độ dài n được tạo thành -1,0 hoặc 1 với xác suất 1/4, 1/2, / 14 của mỗi giá trị. Sau đó, nó tính toán các sản phẩm bên trong giữa F và mỗi cửa sổ có độ dài n cho đến khi tìm thấy một sản phẩm bên trong khác không. Nó thêm 1 leadingzerocounts
vào mỗi vị trí, nó tìm thấy một sản phẩm bên trong bằng không.
Trạng thái
Perl . Chậm lại 2,7 lần bởi @tobyink. (So với pypy không cpython.)
J . Tăng tốc 39 lần bởi @Eelvex.
- C . Tăng tốc 59 lần bởi @ace.
- Julia . Nhanh hơn 197 lần không bao gồm thời gian khởi động trước @ một phút nữa. Tăng tốc 8,5 lần bao gồm cả thời gian khởi động (nhanh hơn khi sử dụng 4 bộ xử lý trong trường hợp này hơn 8).
- Fortran . 438 lần tăng tốc bởi @ bán ngoài.
- Rpython . Tăng tốc gấp 256 lần bởi @primo.
- C ++ . Tăng tốc 508 lần bởi @ilmale.
(Tôi đã dừng thời gian cải tiến mới vì chúng quá nhanh và quá nhỏ.)
Nó đã chỉ ra rằng thời gian dưới một giây là không đáng tin cậy và cũng có một số ngôn ngữ có chi phí khởi đầu. Đối số là nếu bạn bao gồm rằng bạn cũng nên bao gồm thời gian biên dịch của C / C ++, v.v ... Dưới đây là thời gian cho mã nhanh nhất với số lần lặp tăng lên 100.000.
- Julia . 42 giây bởi @ thêm một phút nữa.
- C ++ . 14 giây bởi @GuySirton.
- Fortran . 14s bởi @ bán ngoài.
- C ++ . 12s bởi @ilmale.
- Rpython . 18s bởi @primo.
- C ++ . 5 bởi @Stefan.
Người chiến thắng là .. Stefan!
Theo dõi thử thách được đăng. Làm thế nào cao, bạn có thể đi? (Một thách thức mã hóa + thuật toán) . Cái này khó hơn.