Ini adalah tindak lanjut dari Seberapa lambat sebenarnya Python? (Atau seberapa cepat bahasa Anda?) .
Ternyata agak terlalu mudah untuk mendapatkan speedup x100 untuk pertanyaan terakhir saya. Bagi mereka yang telah menikmati tantangan tetapi menginginkan sesuatu yang lebih keras di mana mereka benar-benar dapat menggunakan keterampilan tingkat rendah mereka, inilah bagian II. Tantangannya adalah untuk mendapatkan speedup x100 untuk kode python berikut seperti yang diuji di komputer saya.
Untuk membuatnya lebih sulit, saya menggunakan pypy kali ini. Waktu saat ini bagi saya adalah 1 menit dan 7 detik menggunakan pypy 2.2.1.
Aturan
- Orang pertama yang mengirimkan kode yang dapat saya jalankan, sudah benar dan x100 kali lebih cepat di komputer saya akan diberikan hadiah 50 poin.
- Saya akan memberikan penghargaan kepada kode tercepat setelah seminggu.
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
Outputnya harus sama dengan
[6335185, 2526840, 1041967, 439735, 193391, 87083, 40635, 19694]
Anda harus menggunakan seed acak dalam kode Anda dan generator nomor acak apa pun yang cukup baik untuk memberikan jawaban yang dekat dengan yang di atas akan diterima.
Mesin Saya Pengaturan waktu akan dijalankan pada mesin saya. Ini adalah instalasi ubuntu standar pada Prosesor Delapan Core AMD FX-8350. Ini juga berarti saya harus dapat menjalankan kode Anda.
Penjelasan kode
Kode ini berulang pada semua larik S dengan panjang n + m-1 yang dibuat untuk -1s dan 1s. Untuk setiap larik S, sampel 1000 larik acak non-nol F dengan panjang n terdiri dari -1,0 atau 1 dengan probabilitas 1/4, 1/2, / 14 untuk mengambil masing-masing nilai. Ini kemudian menghitung produk dalam antara F dan setiap jendela dengan panjang S sampai menemukan produk dalam yang tidak nol. Ia menambahkan 1 leadingzerocounts
pada setiap posisi itu menemukan nol produk dalam.
Status
Perl . 2,7 kali perlambatan oleh @tobyink. (Dibandingkan dengan pypy, bukan cpython.)
J . 39 kali percepatan oleh @Eelvex.
- C . 59 kali dipercepat oleh @ace.
- Julia . 197 kali lebih cepat tidak termasuk waktu mulai dengan @ satu menit lagi. 8,5 kali mempercepat termasuk waktu start up (lebih cepat menggunakan 4 prosesor dalam hal ini dari 8).
- Fortran . 438 kali dipercepat oleh @ semi-ekstrinsik.
- Rpython . 258 kali dipercepat oleh @primo.
- C ++ . 508 kali dipercepat oleh @ilmale.
(Saya berhenti menghitung waktu perbaikan baru karena mereka terlalu cepat dan iters terlalu kecil.)
Itu menunjukkan bahwa waktu di bawah satu detik tidak dapat diandalkan dan juga beberapa bahasa memiliki biaya awal. Argumennya adalah bahwa jika Anda ingin menyertakan Anda juga harus memasukkan waktu kompilasi C / C ++ dll. Berikut adalah timing untuk kode tercepat dengan jumlah iterasi meningkat menjadi 100.000.
- Julia . 42 detik dengan @ satu menit lagi.
- C ++ . 14 detik oleh @GuySirton.
- Fortran . 14s oleh @ semi-ekstrinsik.
- C ++ . 12s oleh @ilmale.
- Rpython . 18-an oleh @primo.
- C ++ . 5d oleh @Stefan.
Pemenangnya adalah .. Stefan!
Tantangan tindak lanjut diposting. Seberapa tinggi Anda bisa pergi? (Tantangan coding + algoritma) . Yang ini lebih sulit.