paso - Pasando argumentos a funciones con parámetros const: ¿es más rápido?
pasar funciones como parametros en c (4)
Considere, por ejemplo:
int sum(int a, int b)
{
return a + b;
}
contra
int sum(const int a, const int b)
{
return a + b;
}
¿Es el segundo enfoque en general más rápido?
Los parámetros de la función en C se copian y envían a la función, de modo que los cambios dentro de la función no afecten los valores originales. Mi razonamiento es que en la segunda sum
anterior, el compilador sabe con seguridad que a
y b
no están modificados dentro de la función, por lo que puede pasar los valores originales sin copiarlos primero. Por eso creo que la segunda sum
es más rápida que la primera. Pero realmente no lo sé. En el ejemplo simple particular de la sum
anterior, las diferencias, si las hay, deben ser mínimas.
Edición: El ejemplo de la sum
es solo para ilustrar mi punto. No espero que en este ejemplo particular haya grandes diferencias. Pero me pregunto si, en situaciones más complicadas, el compilador puede explotar el modificador de const
en un parámetro de función para hacer que la función sea más rápida. Dudo que el compilador siempre pueda determinar si un parámetro se cambia dentro de una función (de ahí mi segunda pregunta a continuación); por lo tanto, espero que cuando encuentre un modificador de const
, haga algo diferente que cuando no hay un modificador de const
.
Pregunta: En general, una función será más rápida cuando sus argumentos sean const
, que cuando no lo sean.
Pregunta 2: En general, ¿puede un compilador de C (teóricamente) determinar siempre si un parámetro de función se cambia dentro de la función?
Aunque llega tarde a la fiesta, un compilador podría poner variables definidas como const en un bloque / segmento de memoria de solo lectura, de modo que si se intentara escribir en la dirección, mediante algún puntero para la actividad, la escritura en la memoria provocaría un error. excepción en tiempo de ejecución.
- Jamey
La respuesta probablemente depende de su compilador, del nivel de optimización y de si el compilador decide integrar la función. Si tiene curiosidad por estas cosas, es fácil mirar el ensamblaje real producido por su compilador y descubrirlo.
No. Ambos deben ser de la misma velocidad. por su razón, suponga que pasa los valores originales para sumar la función, ¿qué tal un código de la función suma modifica el valor original, por ejemplo, otro hilo?
En general, la const no tiene impacto en el rendimiento de los argumentos. Afecta el rendimiento si la constante es una variable local / global porque algunos cálculos se pueden mover al tiempo de compilación como si fuera una constante.
Respuesta corta: No
Larga respuesta, no, con prueba.
Corrí esta prueba, un par de veces, y no vi ninguna diferencia de tiempo real, en mi MacBook pro compilado con el sonido:
int add(int a, int b)
{
return a + b;
}
const int cadd(const int a, const int b)
{
return a + b;
}
int main (int argc, char * argv[])
{
#define ITERS 1000000000
clock_t start = clock();
int j = 0;
for (int i = 0; i < ITERS; i++)
{
j += add(i, i + 1);
}
printf("add took %li ticks/n", clock() - start);
start = clock();
j = 0;
for (int i = 0; i < ITERS; i++)
{
j += cadd(i, i + 1);
}
printf("cadd took %li ticks/n", clock() - start);
return 0;
}
Salida
add took 4875711 ticks cadd took 4885519 ticks
Sin embargo, estos tiempos deberían tomarse con un poco de sal, ya que el clock
no es el más preciso de las funciones de tiempo, y puede ser influenciado por otros programas en ejecución.
Entonces, aquí está el ensamblado comparado generado:
_add:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %esi
addl -8(%rbp), %esi
movl %esi, %eax
popq %rbp
ret
_cadd:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl -4(%rbp), %esi
addl -8(%rbp), %esi
movl %esi, %eax
popq %rb
Entonces, como puedes ver, no hay diferencia entre los dos. Pasar un argumento como const
es solo una sugerencia para quien llama, el argumento no se modificará y, en un escenario simple como el descrito anteriormente, no se obtendrá ningún ensamblaje diferente compilado.