2013-05-16 14 views
7

Ich revite mein neurales Netz von reinem Python zu numpy, aber jetzt arbeitet es noch langsamer. Also habe ich versucht, diese zwei Funktionen:Warum ist Numpy langsamer als Python? Wie man den Code besser macht

def d(): 
    a = [1,2,3,4,5] 
    b = [10,20,30,40,50] 
    c = [i*j for i,j in zip(a,b)] 
    return c 

def e(): 
    a = np.array([1,2,3,4,5]) 
    b = np.array([10,20,30,40,50]) 
    c = a*b 
    return c 

timeit d = 1,77135205057

timeit e = 17,2464673758

Numpy ist 10mal langsamer. Warum ist es so und wie benutzt man numpy richtig?

+0

Vielleicht verwandt: http://stackoverflow.com/questions/5956783/numpy-float-10x-slower-than-butintin-in-arithmetic- operations –

+1

sollten Sie größere Array für diese Art von Test verwenden –

Antwort

14

Ich würde annehmen, dass die Diskrepanz ist, weil Sie Listen und Arrays in e erstellen, während Sie nur Listen in d erstellen. Bedenken Sie:

import numpy as np 

def d(): 
    a = [1,2,3,4,5] 
    b = [10,20,30,40,50] 
    c = [i*j for i,j in zip(a,b)] 
    return c 

def e(): 
    a = np.array([1,2,3,4,5]) 
    b = np.array([10,20,30,40,50]) 
    c = a*b 
    return c 

#Warning: Functions with mutable default arguments are below. 
# This code is only for testing and would be bad practice in production! 
def f(a=[1,2,3,4,5],b=[10,20,30,40,50]): 
    c = [i*j for i,j in zip(a,b)] 
    return c 

def g(a=np.array([1,2,3,4,5]),b=np.array([10,20,30,40,50])): 
    c = a*b 
    return c 


import timeit 
print timeit.timeit('d()','from __main__ import d') 
print timeit.timeit('e()','from __main__ import e') 
print timeit.timeit('f()','from __main__ import f') 
print timeit.timeit('g()','from __main__ import g') 

Hier werden die Funktionen f und g vermeiden Neuerstellung der Listen/Arrays jedes Mal um und wir bekommen sehr ähnliche Leistung:

1.53083586693 
15.8963699341 
1.33564996719 
1.69556999207 

Beachten Sie, dass die Liste-comp + zip noch gewinnt. wenn wir die Anordnungen ausreichend groß Allerdings machen, gewinnt numpy Hände:

t1 = [1,2,3,4,5] * 100 
t2 = [10,20,30,40,50] * 100 
t3 = np.array(t1) 
t4 = np.array(t2) 
print timeit.timeit('f(t1,t2)','from __main__ import f,t1,t2',number=10000) 
print timeit.timeit('g(t3,t4)','from __main__ import g,t3,t4',number=10000) 

Meine Ergebnisse sind:

0.602419137955 
0.0263929367065 
3
import time , numpy 
def d(): 
    a = range(100000) 
    b =range(0,1000000,10) 
    c = [i*j for i,j in zip(a,b)] 
    return c 

def e(): 
    a = numpy.array(range(100000)) 
    b =numpy.array(range(0,1000000,10)) 
    c = a*b 
    return c 



#python ['0.04s', '0.04s', '0.04s'] 
#numpy ['0.02s', '0.02s', '0.02s'] 

versuchen, es mit größeren Arrays ... sogar mit dem Aufwand zur Erstellung Arrays numpy ist viel schneller

2

numpy Datenstrukturen ist langsamer auf das Hinzufügen/Konstruktion

Hier einige Tests:

from timeit import Timer 
setup1 = '''import numpy as np 
a = np.array([])''' 
stmnt1 = 'np.append(a, 1)' 
t1 = Timer(stmnt1, setup1) 

setup2 = 'l = list()' 
stmnt2 = 'l.append(1)' 
t2 = Timer(stmnt2, setup2) 

print('appending to empty list:') 
print(t1.repeat(number=1000)) 
print(t2.repeat(number=1000)) 

setup1 = '''import numpy as np 
a = np.array(range(999999))''' 
stmnt1 = 'np.append(a, 1)' 
t1 = Timer(stmnt1, setup1) 

setup2 = 'l = [x for x in xrange(999999)]' 
stmnt2 = 'l.append(1)' 
t2 = Timer(stmnt2, setup2) 

print('appending to large list:') 
print(t1.repeat(number=1000)) 
print(t2.repeat(number=1000)) 

Ergebnisse:

appending to empty list: 
[0.008171333983972538, 0.0076482562944814175, 0.007862921943675175] 
[0.00015624398517267296, 0.0001191077336243837, 0.000118654852507942] 
appending to large list: 
[2.8521017080411304, 2.8518707386717446, 2.8022625940577477] 
[0.0001643958452675065, 0.00017888804099541744, 0.00016711313196715594] 
-1

Ich glaube nicht numpy langsam ist, weil es die Zeit Rechnung erforderlich zu schreiben und zu debuggen nehmen müssen. Je länger das Programm ist, desto schwieriger ist es, Probleme zu finden oder neue Funktionen hinzuzufügen (Programmierzeit). Aus diesem Grund ermöglicht die Verwendung einer höheren Programmiersprache bei gleicher Intelligenz, Zeit und Erfahrung die Erstellung eines komplexen und potenziell effizienteren Programms.

Wie auch immer, einige interessante Tools zur Optimierung sind:

- Psyco ist ein JIT (just in time "Echtzeit"), die der Code zur Laufzeit optimiert.

- Numexpr, Parallelisierung ist eine gute Möglichkeit, die Ausführung eines Programms zu beschleunigen, vorausgesetzt, dass es ausreichend trennbar ist.

- weben ein Modul innerhalb NumPy ist Python und C. Eine seiner Funktionen zu kommunizieren, ist zu blitz, die eine Reihe von Python nimmt, übersetzt die transparent C, und jedes Mal, wenn der Anruf optimierte Version ausgeführt wird. Wenn man diese erste Umwandlung macht, benötigt man etwa eine Sekunde, aber höhere Geschwindigkeiten erhalten im Allgemeinen alle oben genannten Punkte.Es ist nicht wie Numexpr oder Psyco Bytecode, oder Schnittstelle C wie NumPy, sondern Ihre eigene Funktion direkt in C geschrieben und vollständig kompiliert und optimiert.

Verwandte Themen