2016-10-31 31 views
8

Ben aşağıdaki kodu hızlandırmak gerekir:Bu iki satırlı kodu nasıl hızlandırabilirim?

for i in range(0, 2**N): 

    output[i] = f(np.array(map(int, bin(i)[2:].zfill(N)))) 

N civarında 30, bu nedenle kodu (Dizüstü bilgisayarımda yaklaşık 33 saat sürer) çok yavaştır. f() işlevinin argümanı, i dizininin ikili gösterimidir ve f(), rasgele bir vektörleştirilebilir işlev olabilir. Ben uzman değilim, ama kodu hızlandırmak içinargümanını vectorize etmem gerektiği anlamına gelen for döngüsünden kurtulmayı düşünüyordum. Başka bir deyişle, 0'dan 2**N'a kadar sayıların ikili gösterimleriyle bir matris oluşturmam gerekiyor. Bu aşağıdaki kod üzerinden elde edilebilir:

list(itertools.product([0, 1], repeat=N)) 

Ben this link de bulunduğunu bildirdi. Ancak, bana itertools'un çok yavaş olduğu ve 2**30'un yaklaşık bir milyar olduğu için çok fazla bellek gerektirdiği görülüyor.

Bu kodu daha hızlı yapmak için herhangi bir öneriniz var mı? Şimdiden teşekkürler.

+0

“Çıktının” son değerinin tümünü atıyor gibisiniz. – user2357112

+8

Bir milyar eleman dizisi üretmek yerine, neden bir jeneratör olarak yeniden yazılmıyor? – dawg

+0

Jeneratörleri ve "verim" komutlarını arayın. – oliversm

cevap

6

daima profili: öyle değil dizeleri ile uğraşmak zorundadır çünkü

>>> timeit.timeit("for i in range(0, 2**N): numpy.array(map(int, bin(i)[2:].zfill(N)))", "import numpy; N=5", number=100000) 
26.472519159317017 
>>> timeit.timeit("for t in itertools.product((0, 1), repeat=N): numpy.array(t)", "import numpy, itertools; N=5", number=100000) 
6.129688024520874 

Sen itertools.product yöntem oldukça hızlı olduğunu görebilirsiniz.

Sorun çoğu zaman f işlevinde harcanmış olabilir.

Başka bir çözüm, f bir tamsayı kabul etmek ve bir ikili alan olarak kullanmak olabilir.

+0

Ek: Yeni bir MBP'de 2^24 'pass 'işlemleri için zaman: sadece' range' ile 883ms, 'xrange' ile 501ms,' pass' ve 'range' işlev çağrısı ile 1.92s, ve işlev için 1.58s + xrange'i çağır. –

+0

Cool, 'N = 20' ile denedim ve 1,5 dakika yerine 1 dakika sürdü. Bu büyük 'N' için çok zaman kazandıracaktır. N = 30 için 33 saat vs 33 sanırım. – user2983638