2012-10-01 29 views
7

¿Hay una diferencia de rendimiento o preferencia de estilo entre estas dos formas de escribir declaraciones if? Básicamente es lo mismo, la condición 1 se cumplirá solo una vez, mientras que la otra condición se cumplirá en cualquier otro momento. ¿Debería la condición que se cumple solo una vez ser primero o segundo? ¿Hace una diferencia en cuanto al rendimiento? Prefiero la primera manera si el rendimiento es el mismo.¿Rendimiento o diferencia de estilo entre "si" y "si no"?

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, por favor, no cambie [código en preguntas] (http://stackoverflow.com/review-beta/suggested-edits/738615); deje un comentario para OP en su lugar y sugiera el cambio. – Ben

+1

Su cuello de botella real es probable que sea 'write_data'. No te preocupes por las cosas pequeñas. Si tiene un problema de rendimiento, perfile y optimice. –

+0

¿Qué estás escribiendo? Lo más probable es que ya esté almacenado en el búfer o que permita establecer el tamaño del búfer. –

Respuesta

2

No debería haber ninguna diferencia de rendimiento (en todo caso, creo que la segunda sería menos eficiente), pero sólo tiene que utilizar el que sea más claro para usted. Me gusta el primero mejor también. :)

Si ve la diferencia más tarde, siga adelante y cámbiela, pero ya sabe lo que dice: la optimización prematura es la raíz de todo mal.

5

Creo que la LECTURA es más importante que la ventaja de rendimiento, si es que existe, aunque no creo que haya ninguna diferencia.

Por lo tanto, use la 1 ª manera, porque es más fácil de entender.

0

No puedo verificar esto, pero usando el sentido común, creo que el primero funcionaría un poco mejor. El segundo está evaluando el < y luego evalúa el no. Esa es una operación adicional. Y lo hace todo el tiempo. Además, intuitivamente, el primero tiene más sentido.

9

En su ejemplo, if no se necesita en absoluto:

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 

Creo que esta es la manera más eficiente en su caso.

+0

Heh, buen punto: P – Ryan

+0

Es verdad, simplemente no estaba seguro de si había alguna condición en la que los datos [offset: offset + max_chunk] estuvieran fuera de rango ya que max_chunk es un valor fijo. – ss41153

+0

Funciona correctamente aunque la condición esté fuera de rango :) – defuz

7

Bueno, vamos a tratar:

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 

obtenemos:

%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, no es una gran cantidad de diferencias aquí. Incluso con una x más grande, las diferencias son mínimas.

Debo decir que estoy un poco sorprendido, esperaba que la versión directa (f) fuera ligeramente más eficiente que la versión not (g).

Moral: haz lo que quieras.

+0

Tenga en cuenta que 'not chunk Bakuriu

+1

Eché un vistazo a los códigos de operación de python para esto, cambia entre POP_JUMP_IF_FALSE a POP_JUMP_IF_TRUE para las dos versiones. De ahí por qué son muy similares a la velocidad. –

2

Otros han notado que la legibilidad es (por lo general) más importante y que realmente no se necesita la forma en que se presenta el ejemplo. Además, está la sierra antigua: "Premature optimization is the root of all evil".

Dicho esto, la mejor manera de descubrir el rendimiento es probar. Por lo tanto, puse sus dos ejemplos en funciones (cambiantes range[0,1023]-range(0, 1023) para que todo funcione) llamado el primer ejemplo 'without_not' y el segundo ejemplo 'with_not', y ha creado un sencillo principal para poner a prueba utilizando el 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() 

Luego ejecuté varias pruebas. Como yo, y otras respuestas, esperaba, la versión sin el not funcionó un poco - aproximadamente 0.6% - más rápido en cada prueba; no es suficiente para preocuparse, IMO. (Bueno, puede haber algunos casos en los que sea importante, pero si ese fuera el caso, recomendaría C o algún otro lenguaje compilado.)

0

si hay una diferencia de rendimiento? sí, el procesador tiene que hacer un salto predictivo en caso de declaraciones if-else. notarás la diferencia? de ninguna manera. su compilador/optimizador pondrá su código al revés antes de la ejecución. su cálculo probablemente no tome unos pocos miles de años para que importe. es probable que incluso no use el sistema en tiempo real.

como otros dijeron: enfoque en la facilidad de lectura, no preoptimize partes sin importancia

Cuestiones relacionadas