retorno paso pasar parametros funciones ejemplos con como c const function-parameter

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.