2008-09-26 11 views
14

Tengo un procedimiento con una gran cantidad de¿Hay una diferencia de rendimiento entre inc (i) e i: = i + 1 en Delphi?

i := i +1; 

en ella y creo

inc(i); 

se ve mucho mejor. ¿Hay una diferencia de rendimiento o la llamada de función acaba de ser introducida por el compilador? Sé que esto probablemente no importa para mi aplicación, solo tengo curiosidad.

EDIT: Hice una cierta medición del rendimiento y encontré la diferencia de ser muy pequeño, de hecho tan pequeño como 5.1222741794670901427682121946224e-8! Entonces realmente no importa. Y las opciones de optimización realmente no cambiaron mucho el resultado. Gracias por todos los consejos y sugerencias!

+0

"5.1222741794670901427682121946224e-8" ?? ¿Qué pasa con "5.12e-8"? :-) No puedo pensar en ninguna aplicación práctica que requiera 32 dígitos significativos, ni ninguna medición con la mitad de ellos correctos. "Un matemático quiere pi a 1 billón de dígitos, a un ingeniero pi igual a 3.14" – stevenvh

+0

Jeje, bueno realicé una prueba y ese fue el resultado, así que solo lo corté y pegué, de ahí la gran cantidad de dígitos :) –

Respuesta

7

Los compiladores modernos optimizan el código.
inc (i) ei: = i + 1; son más o menos lo mismo.

Use el que prefiera.

Editar: Como Jim McKeeth corrigió: con la comprobación de desbordamiento hay una diferencia. Inc no hace una comprobación de rango.

+3

¡Incorrecto! Active la comprobación de rango o la comprobación de desbordamiento y observe el desmontaje. –

3

Puede verificarlo en la ventana de la CPU mientras realiza la depuración. Las instrucciones generadas de la CPU son las mismas para ambos casos.

Estoy de acuerdo Inc(I); se ve mejor, aunque esto puede ser subjetivo.

Corrección: acabo de encontrar esto en la documentación Inc:

"En algunas plataformas, Inc puede generar código optimizado, especialmente útil en bucles apretados."

lo que es probablemente recomendable pegarse a Inc.

+0

Inc salta la verificación de rango –

1

Siempre se puede escribir dos piezas de código (en procedimientos separados), poner un punto de interrupción en el código y comparar el ensamblador en la ventana de la CPU.

En general, usaría inc (i) siempre que se use como un bucle/índice de algún tipo, y + 1 donde quiera que el 1 haga que el código sea más fácil de mantener (es decir, podría concebirse un cambio a otro entero en el futuro) o simplemente más legible desde un punto de vista de algoritmo/especificación.

+0

no es inc (i, 1) tan claro y fácil de cambiar a inc (i, 2)? – Argalatyr

0

"En algunas plataformas, Inc puede generar código optimizado, especialmente útil en bucles estrechos". Para un compilador optimizado como Delphi no le importa. Se trata de compiladores antiguos (por ejemplo, Turbo Pascal)

6

Todo depende del tipo de "i". En Delphi, uno normalmente declara variables de bucle como "i: Integer", pero bien podría ser "i: PChar", que se resuelve en PAnsiChar en todo lo que está debajo de Delphi 2009 y FPC (supongo que aquí), y en PWideChar en Delphi 2009 y Delphi.NET (también adivinando).

Dado que Delphi 2009 puede hacer puntero-matemáticas, Inc (i) también se puede hacer en punteros tipeados (si están definidos con POINTER_MATH activado).

Por ejemplo:

type 
    PSomeRecord = ^RSomeRecord; 
    RSomeRecord = record 
    Value1: Integer; 
    Value2: Double; 
    end; 

var 
    i: PSomeRecord; 

procedure Test; 
begin 
    Inc(i); // This line increases i with SizeOf(RSomeRecord) bytes, thanks to POINTER_MATH ! 
end; 

Como los otros anwsers ya se ha dicho: Es relativly fácil ver lo que el compilador hace de su código mediante la apertura:

Vistas> depuración de Windows> Windows CPU > Desmontaje

Tenga en cuenta, que las opciones del compilador como la optimización, OVERFLOW_CHECKS y RANGE_CHECKS podría influir en el resultado final, por lo que Shoul Tenga cuidado de tener la configuración de acuerdo a su preferencia.

Un consejo al respecto: en cada unidad, $ INCLUYE un archivo que dirige las opciones del compilador, de esta manera, no perderá configuraciones cuando su .bdsproj o .dproj se dañe de alguna manera. (Consulte el código fuente del JCL para ver un buen ejemplo al respecto)

16

Hay una gran diferencia si Comprobación de desbordamiento está activada. Básicamente Inc no realiza la verificación de desbordamiento. Haga lo que se sugirió y utilice la ventana de desensamblaje para ver la diferencia cuando tenga activadas esas opciones de compilación (es diferente para cada una).

Si esas opciones están desactivadas, entonces no hay diferencia. Regla de oro, utilice Inc cuando no le importe una falla de comprobación de rango (¡ya que no obtendrá una excepción!).

+0

+1 ¡Es bueno saberlo! – SOUser

+1

Esto no parece cierto. Inc() ** does ** overflow checking cuando esta opción está activada. Probado en D2007 y XE8. Por lo tanto, no hay absolutamente ninguna diferencia entre 'Inc (i)' y 'i: = i + 1'. –