Digamos que tengo una función donde el parámetro se pasa por valor en lugar de const-reference. Además, supongamos que solo se usa el valor dentro de la función, es decir, que la función no intenta modificarlo. En ese caso, ¿el compilador podrá darse cuenta de que puede pasar el valor por const-reference (por razones de rendimiento) y generar el código en consecuencia? ¿Hay algún compilador que haga eso?¿El compilador optimiza los parámetros de función pasados por valor?
Respuesta
Si pasa una variable en lugar de una temporal, el compilador no puede optimizar la copia si el constructor de copia hace algo que notaría al ejecutar el programa ("comportamiento observable": entradas/salidas, o cambio de variables volátiles).
Aparte de eso, el compilador es libre de hacer todo lo que quiera (solo tiene que parecerse al comportamiento observable como-si no se hubiera optimizado en absoluto).
Solo cuando el argumento es un valor r (más temporal), el compilador puede optimizar la copia al parámetro de valor por valor aunque el constructor de la copia tenga efectos colaterales observables.
Um, ¿no está copiando exento de la regla de si? Pensé que copiar era lo único que el compilador podía eliminar sin preocuparse por las consecuencias. – sbi
Creo que el compilador no necesita garantizar que el constructor de copia no tenga un "comportamiento observable", ya que esa es la misma premisa por la cual el compilador puede elide realizar copias de temporarios. –
@sbi copia está exenta si copia desde un valor r. Si copia de un lvalue, no lo es. Si pasa un valor r y el compilador ingresa el código de la función llamada, puede optimizar todo lo que quiera (de hecho, he visto que GCC optimiza cientos de líneas de ensamblaje con tres o cuatro llamadas anidadas en solo dos o tres líneas) . Ver 12.8/15 en la especificación C++ 03. –
Solo si la función no se exporta, existe la posibilidad de que el compilador convierta call-by-reference en call-by-value (o viceversa).
De lo contrario, debido a la convención de llamadas, la función debe mantener la semántica call-by-value/reference.
Pero las copias en línea de esta pueden, por supuesto, optimizarse, aunque la versión externamente visible de la función no lo esté. –
Este post es una excelente referencia a este tipo de optimización: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Creo que le falta el sentido del artículo (al menos en el contexto de esta pregunta). En ese artículo, se hará una copia de una manera u otra, y * se modificará *. – UncleBens
UncleBens: Veo lo que quiere decir, pero pensé que la publicación del blog arroja algo de luz sobre el tipo de optimización que un compilador es capaz de hacer, por lo que sentí que no estaba completamente fuera de tema. Piense en el comentario "¿significa esto que podemos eliminar completa y definitivamente el viejo operador de referencia y copia paso a paso?" A lo que D. Abrahams responde: "¡En realidad, sí! Volcarlo ayer. " – Francesco
Con todas las optimizaciones que la respuesta es generalmente "tal vez". La única manera de comprobar es examinar el conjunto de salida y ver lo que realmente está haciendo. Si el estándar lo permite, ya sea que realmente suceda o no depende de los caprichos del compilador. No debe confiar en que esto ocurra porque un cambio arbitrario en cualquier parte de su base de código puede cambiar la heurística utilizada por el optimizador, lo que podría hacer que deje de realizar una determinada optimización.
Juega seguro: codifícalo como te propones, pasa por referencia si eso es lo que quieres. Sin embargo, si está escribiendo código de plantilla que podría funcionar en tipos de cualquier tamaño, la elección no es tan clara. Personalmente, estaría del lado de pasar por la referencia de referencia - el compilador podría también realizar una optimización diferente, donde un tipo pequeño que puede caber dentro del tamaño de una referencia se pasa por valor, en lugar de por referencia constante. Pero, de nuevo, podría suceder, puede que no.
No estoy al tanto de ninguna garantía general de que esto se haga, pero si la función llamada está en línea, esto permitirá al compilador ver que se está realizando una copia innecesaria, y si el nivel de optimización es lo suficientemente alto, la operación de copia sería eliminada. GCC puede hacer esto al menos.
Es posible que desee pensar si la clase de este valor de parámetro tiene un constructor de copia o no. Si no lo hace, entonces la diferencia de rendimiento entre pass-by-value y pass-by-const-ref es probablemente insignificante.
Por otro lado, si la clase tiene un constructor de copia que hace cosas, entonces la optimización que está esperando probablemente no ocurra porque el compilador no puede eliminar la llamada al constructor; no puede saber que los efectos secundarios del constructor no son importantes para ti.
Puede obtener más respuestas útiles si dice cuál es la clase del parámetro, o si es una clase personalizada, describe qué campos tiene y si tiene un constructor de copia.
- 1. El compilador C# no optimiza los moldes innecesarios
- 2. ¿Cuándo el compilador optimiza mi código
- 3. ¿Cómo un compilador optimiza tan bien esta función factorial?
- 4. ¿Otras referencias a cómo el compilador de Stalin optimiza brutalmente?
- 5. Comprobación de los parámetros pasados utilizando nula - JavaScript
- 6. Obtener todos los argumentos y valores pasados a una función
- 7. ¿El compilador de C# optimiza las propiedades de recuento?
- 8. función de php para variables no definidas pasados por referencia
- 9. ¿Cuáles son los parámetros pasados a cvFindContours() en JavaCV?
- 10. Modificando argumentos 'pasados por valor' dentro de una función y usándolos como variables locales
- 11. Valor predeterminado para los parámetros de función en VB6
- 12. Flex: ¿el compilador flex optimiza automáticamente los activos incrustados de PNG?
- 13. ¿Qué hace el compilador de C++ cuando aparecen los parámetros por defecto ambiguos?
- 14. JSON con valor de función con los parámetros
- 15. ¿Para qué sirve/optimiza la clave del compilador de C#?
- 16. compilador Java renombrar automáticamente los parámetros (ofuscadoras)
- 17. ¿Por qué C++ 11 tiene movimientos implícitos para los parámetros de valor, pero no para los parámetros de valor?
- 18. función de PHP por defecto de parámetros
- 19. ¿Los parámetros de valor se mueven implícitamente cuando se devuelve por valor?
- 20. ¿Por qué son los parámetros de función de tipo size_t?
- 21. ¿Es el colon inicial para los nombres de parámetros pasados a PDOStatement :: bindParam() opcional?
- 22. ¿Por qué la mayoría de los lenguajes de programación utilizan una evaluación entusiasta para los argumentos pasados a una función?
- 23. ¿Filtros de acción MVC usando parámetros pasados a ActionResult?
- 24. ¿Cómo puedo estar seguro de que el compilador no optimiza mi prueba de rendimiento?
- 25. ¿En qué caso, esta función no devolverá un valor? ¿Por qué el compilador informa un error?
- 26. ¿El compilador JDK optimiza el uso de clases anónimas sin variables de instancia?
- 27. cómo probar los parámetros pasados a un controlador en los rieles 3, usando rspec?
- 28. Delphi paso de parámetros por referencia o por valor/copia
- 29. ¿El compilador JIT optimiza (en línea) las declaraciones de variables innecesarias?
- 30. Cómo obtener todos los argumentos pasados a la función (frente a $ args opcionales)
Tenga en cuenta que generalmente el * compilador * solo considera una TU a la vez. En la práctica, las optimizaciones que implican que el llamante haga algo diferente, en función de lo que sucede en el destinatario, solo funcionan si la definición de la función está disponible en la TU de la persona que llama, y / o con la optimización del tiempo de enlace. –
Pregunta relacionada: http://stackoverflow.com/questions/2043974 –