2013-06-21 13 views
5

corro python 2.7 e MATLAB R2010a sulla stessa macchina, non fare nulla, e mi dà 10x diversa in termini di velocitàciclo for in Python è 10 volte più lento di MATLAB

ho guardato on-line, e sentito che dovrebbe essere la stessa ordine. Python rallenterà ulteriormente come se l'operatore di istruzioni e matematica nel ciclo for

La mia domanda: è questa la realtà? o c'è qualche altro modo di lasciarli nello stesso ordine di velocità?


Ecco il codice python

import time 

start_time = time.time() 

for r in xrange(1000): 

     for c in xrange(1000): 

     continue 

elapsed_time = time.time() - start_time 

print 'time cost = ',elapsed_time 

Output: time cost = 0.0377440452576

Ecco codice MATLAB

tic 

for i = 1:1000 

    for j = 1:1000 

    end 

end 

toc 

Output: Escaped time is 0.004200 seconds

+0

Non lo sono anche se c'è nessuna differenza con lo strumento di ottimizzazione del compilatore, ma hai provato a passare invece di continuare? Forse se aggiungessi un calcolo molto semplice, 't = t + 1' allora cambierebbe. – slbass

+0

Testare il ciclo con 'python -m timeit' mostra che usare' pass' è un po 'più lento di 'continue', ma non in modo significativo. Sulla mia macchina i cicli richiedono 16 msec, ovvero meno della metà di quanto afferma l'OP. Si noti inoltre che MATLAB ha un [JIT] (http://www.matlabtips.com/matlab-is-no-longer-slow-at-for-loops/), quindi tali differenze sono da aspettarsi * specialmente * con semplici loop. – Bakuriu

+3

Potrebbe essere utile inserire qualcosa nel ciclo, nel caso in cui Matlab sia abbastanza intelligente da realizzare i loop in realtà non fanno nulla, e li ha ottimizzati. – Aya

risposta

2

Se Python execut Ion Performance è veramente importante per voi, si potrebbe dare un'occhiata a PyPy

ho fatto il test:

import time 
for a in range(10): 
    start_time = time.time() 
    for r in xrange(1000): 
     for c in xrange(1000): 
      continue 

    elapsed_time = time.time()-start_time 
    print elapsed_time 

con standard di Python 2.7.3, ottengo:

0.0311839580536 
0.0310959815979 
0.0309510231018 
0.0306520462036 
0.0302460193634 
0.0324130058289 
0.0308878421783 
0.0307397842407 
0.0304911136627 
0.0307500362396 

mentre, usando PyPy 1.9.0 (che corrisponde a Python 2.7.2), ottengo:

0.00921821594238 
0.0115230083466 
0.00851202011108 
0.00808095932007 
0.00496387481689 
0.00499391555786 
0.00508499145508 
0.00618195533752 
0.005126953125 
0.00482988357544 

L'accelerazione o f PyPy è davvero sorprendente e diventa davvero visibile quando le ottimizzazioni del compilatore JIT superano i costi. Questo è anche il motivo per cui ho introdotto il ciclo aggiuntivo. Per questo esempio, assolutamente nessuna modifica del codice era necessaria.

+3

Il problema con PyPy è che non supporta ancora NumPy, quindi non è una sostituzione MATLAB ideale. –

8

Il motivo per cui ciò accade è correlato al compilatore JIT, che sta ottimizzando il ciclo MATLAB. È possibile disabilitare/abilitare l'acceleratore JIT utilizzando feature accel off e feature accel on. Quando disabiliti l'acceleratore, i tempi cambiano drasticamente.

MATLAB con Accel on: Elapsed time is 0.009407 seconds.

MATLAB con Accel off: Elapsed time is 0.287955 seconds.

pitone: time cost = 0.0511920452118

Così l'acceleratore JIT sta causando direttamente l'aumento di velocità che si stanno notando. C'è un'altra cosa che dovresti considerare, che è legata al modo in cui hai definito gli indici di iterazione. In entrambi i casi, MATLAB e Python, hai usato Iterator per definire i tuoi loop. In MATLAB crei i valori attuali aggiungendo le parentesi quadre ([]), e in python usi range invece di xrange.Quando si apportano le modifiche

% MATLAB 
for i = [1:1000] 
    for j = [1:1000] 

# python 
for r in range(1000): 
    for c in range(1000): 

I tempi diventano

MATLAB con Accel on: Elapsed time is 0.338701 seconds.

MATLAB con Accel off: Elapsed time is 0.289220 seconds.

pitone: time cost = 0.0606048107147

Una considerazione finale è se dovessi aggiungere un calcolo veloce al ciclo. cioè t=t+1. Poi i tempi diventano

MATLAB con Accel on: Elapsed time is 1.340830 seconds.

MATLAB con Accel off: Elapsed time is 0.905956 seconds. (Sì off è stato più veloce)

pitone: time cost = 0.147221088409

penso che la morale è che la le velocità di calcolo di loop for, out-of-the-box, sono paragonabili per cicli estremamente semplici, a seconda della situazione. Tuttavia, ci sono altri strumenti numerici in python che possono velocizzare le cose in modo significativo, numpy e PyPy sono stati allevati finora.

+0

'xrange' di Python è un semplice iteratore. Se vuoi confrontare la versione di MATLAB con quella di Python devi usare plain 'range'. – Bakuriu

+0

@Bakuriu Hai ragione, ho cambiato il mio post per utilizzare l'intervallo e aggiornato il runtime, anche se nulla è cambiato. – slbass

+0

Quali risultati si ottengono confrontando gli stessi blocchi di codice, ma usando 'per i = 1: 1000' di Matlab rispetto a' xrange' di Python 2.x? – Aya

3

L'implementazione di base di Python, CPython, non è pensata per essere super-veloce. Se hai bisogno di un'efficiente manipolazione numerica in stile matlab, usa the numpy package o un'implementazione di Python progettata per un lavoro veloce, come PyPy o anche Cython. (Scrivere un'estensione Python in C, che ovviamente sarà piuttosto veloce, è anche una possibile soluzione, ma in tal caso potresti anche usare numpy e risparmiarti lo sforzo.)

Problemi correlati