2012-10-01 2 views
7

Esiste una differenza di prestazioni o una preferenza di stile tra questi due modi di scrivere se le istruzioni? È fondamentalmente la stessa cosa, la condizione 1 sarà soddisfatta una sola volta mentre l'altra condizione verrà soddisfatta ogni volta. La condizione che si incontra solo una volta deve essere la prima o la seconda? Fa una differenza in termini di prestazioni? Preferisco la 1a via se la performance è la stessa.Le prestazioni o la differenza di stile tra "se" e "se non"?

data = range[0,1023] 
length = len(data) 
max_chunk = 10 

for offset in xrange(0,length,max_chunk): 
    chunk = min(max_chunk,length-offset) 
    if chunk < max_chunk: 
     write_data(data[offset:]) 
    else: 
     write_data(data[offset:offset+max_chunk]) 

vs

data = range[0,1023] 
length = len(data) 
max_chunk = 10 

for offset in xrange(0,length,max_chunk): 
    chunk = min(max_chunk,length-offset) 
    if not chunk < max_chunk: 
     write_data(data[offset:offset+max_chunk]) 
    else: 
     write_data(data[offset:]) 
+0

@Konstantin, si prega di non modificare [codice a domande] (http://stackoverflow.com/review-beta/suggested-edits/738.615); lascia un commento per l'OP e suggerisci il cambiamento. – Ben

+1

Probabilmente il tuo collo di bottiglia sarà 'write_data'. Non sudare le piccole cose. Se hai un problema di prestazioni, profilo e ottimizzazione. –

+0

A cosa stai scrivendo? È probabile che sia già presente nel buffer o che sia possibile impostare la dimensione del buffer. –

risposta

2

non ci dovrebbe essere alcuna differenza di prestazioni (se non del tutto, penso che il secondo sarebbe meno performante), ma basta usare quello che è più chiaro a voi. Mi piace anche il primo. :)

Se trovi che fa la differenza in seguito, allora vai avanti e cambialo, ma sai cosa dicono: l'ottimizzazione prematura è la radice di tutto il male.

5

Penso che la LEGGIBILITÀ sia più importante del vantaggio prestazionale se esiste, anche se non penso ci siano differenze.

Quindi utilizzare il 1o modo, perché è più facile da capire.

0

Non riesco a verificarlo, ma usando il buon senso, penserei che il primo avrebbe prestazioni leggermente migliori. Il secondo sta valutando lo < e poi lo valuta. Questa è un'altra operazione. E lo fa ogni volta. Inoltre intuitivamente il primo ha più senso.

9

Nel tuo esempio, if non è necessaria a tutti:

data = range[0,1023] 
length = len(data) 
max_chunk = 10 

for offset in xrange(0,length,max_chunk): 
    write_data(data[offset:offset+max_chunk]) # It works correctly 

penso che questo sia il modo più efficace nel vostro caso.

+0

Heh, buon punto: P – Ryan

+0

Questo è vero, non ero sicuro se ci fosse qualche condizione in cui i dati [offset: offset + max_chunk] sarebbero fuori portata poiché max_chunk è un valore fisso. – ss41153

+0

Funziona correttamente anche se la condizione non rientra nell'intervallo :) – defuz

7

Bene, proviamo:

x = np.random.rand(100) 

def f(x): 
    z = 0 
    for i in x: 
     if i < 0.5: 
      z += 1 
     else: 
      z += 0 
    return z 

def g(x): 
    z = 0 
    for i in x: 
     if not (i < 0.5): 
      z += 0 
     else: 
      z += 1 
    return z 

otteniamo:

%timeit f(x) 
10000 loops, best of 3: 141 us per loop 
%timeit g(x) 
10000 loops, best of 3: 140 us per loop 

No, non un sacco di differenze qui. Anche con una x più grande, le differenze sono minime.

Devo dire che sono un po 'sorpreso, mi sarei aspettato che la versione diretta (f) fosse leggermente più efficiente della versione (g).

Morale: fai quello che vuoi.

+0

Tieni presente che quel 'non chunk Bakuriu

+1

Ho dato un'occhiata agli opcode python per questo, passa da POP_JUMP_IF_FALSE a POP_JUMP_IF_TRUE per le due versioni. Quindi perché sono molto simili in senso orario. –

2

Altri hanno notato che la leggibilità è (di solito) più importante e che non è realmente necessario se il modo in cui viene presentato l'esempio. Inoltre, c'è la vecchia sega: "Premature optimization is the root of all evil".

Detto questo, il modo migliore per scoprire le prestazioni è testare. Così, ho messo i vostri due esempi in funzioni (che cambiano range[0,1023]-range(0, 1023) a far funzionare le cose) di nome il primo esempio 'without_not' e il secondo esempio 'with_not', e ha creato un semplice principale per testare utilizzando il testit module:

def main(): 
    global outfile 
    outfile = open('test.dat', 'wt') 
    num_tests = 10000 
    without_timer = timeit.Timer(stmt=without_not) 
    with_timer = timeit.Timer(stmt=with_not) 
    print 'without result: ', without_timer.timeit(number=num_tests) 
    print 'with result: ', with_timer.timeit(number=num_tests) 
    outfile.close() 

Quindi ho eseguito diversi test. Come previsto da me e altri risponditori, la versione senza lo not ha funzionato un po '- circa 0.6% - più veloce in ogni test; non abbastanza da preoccuparsi, IMO. (Beh, ci possono essere alcuni casi in cui è importante, ma se fosse il caso raccomanderei C o qualche altro linguaggio compilato.)

0

se ci sarà una differenza di prestazioni? sì, il processore deve fare un salto predittivo in caso di istruzioni if-else. noterai la differenza? non c'è modo. il tuo compilatore/ottimizzatore metterà il tuo codice capovolto prima dell'esecuzione. il tuo calcolo probabilmente non richiederà alcune migliaia di anni per renderlo importante. probabilmente non usi nemmeno il sistema in tempo reale.

Come altri hanno detto: focus sulla leggibilità, non preoptimize componenti non importanti