titledborder poner ejemplo borde java performance methods call

poner - setbounds java



Java, qué tan caro es un método de llamada (12)

¿Sería más óptimo para mí simplemente copiar y pegar las dos líneas en mi método clear () en el constructor en lugar de llamar al método real?

El compilador puede realizar esa optimización. Y también lo puede hacer la JVM. La terminología utilizada por el escritor del compilador y los autores de JVM es "expansión en línea".

Si es así, ¿cuánta diferencia hace?

Mídelo. A menudo, encontrarás que no hace ninguna diferencia. Y si crees que este es un punto de acceso de rendimiento, estás buscando en el lugar equivocado; es por eso que deberás medirlo.

¿Qué pasa si mi constructor realizó 10 llamadas a métodos con cada uno simplemente configurando una variable de instancia a un valor?

De nuevo, eso depende del bytecode generado y cualquier optimización de tiempo de ejecución realizada por la máquina virtual de Java. Si el compilador / JVM puede alinear las llamadas al método, realizará la optimización para evitar la sobrecarga de crear nuevas tramas de pila en tiempo de ejecución.

¿Cuál es la mejor práctica de programación?

Evitando la optimización prematura. La mejor práctica es escribir código legible y bien diseñado, y luego optimizar para los puntos de acceso de rendimiento en su aplicación.

Soy un principiante y siempre he leído que es malo repetir el código. Sin embargo, parece que para no hacerlo, tendrías que tener llamadas a métodos extra por lo general. Digamos que tengo la siguiente clase

public class BinarySearchTree<E extends Comparable<E>>{ private BinaryTree<E> root; private final BinaryTree<E> EMPTY = new BinaryTree<E>(); private int count; private Comparator<E> ordering; public BinarySearchTree(Comparator<E> order){ ordering = order; clear(); } public void clear(){ root = EMPTY; count = 0; } }

¿Sería más óptimo para mí simplemente copiar y pegar las dos líneas en mi método clear () en el constructor en lugar de llamar al método real? Si es así, ¿cuánta diferencia hace? ¿Qué pasa si mi constructor realizó 10 llamadas a métodos con cada uno simplemente configurando una variable de instancia a un valor? ¿Cuál es la mejor práctica de programación?


Como han dicho otros, el costo de la llamada al método es trivial-a-nada, ya que el compilador lo optimizará para usted.

Dicho esto, existen peligros al realizar llamadas de método a métodos de instancia desde un constructor. Corre el riesgo de actualizar más tarde el método de la instancia para que intente usar una variable de instancia que aún no ha sido iniciada por el constructor. Es decir, no necesariamente quiere separar las actividades de construcción del constructor.

Otra pregunta: su método clear () establece la raíz en EMPTY, que se inicializa cuando se crea el objeto. Si luego agrega nodos a VACÍO y luego llama a borrar (), no reiniciará el nodo raíz. ¿Es este el comportamiento que quieres?


Dado el recuerdo de las computadoras modernas, esto es muy económico. Siempre es mejor dividir tu código en métodos para que alguien pueda leer rápidamente lo que está sucediendo. También ayudará a reducir los errores en el código si el error está restringido a un único método con un cuerpo de pocas líneas.


Definitivamente lo dejaría como está. ¿Qué sucede si cambia la lógica clear() ? No sería práctico encontrar todos los lugares donde copió las 2 líneas de código.


El costo de una llamada a un método es la creación (y disposición) de un marco de pila y algunas expresiones de código de bytes adicionales si necesita pasar valores al método.


El patrón que sigo es si este método en cuestión satisfaría uno de los siguientes:

  • ¿Sería útil tener este método disponible fuera de esta clase?
  • ¿Sería útil tener este método disponible en otros métodos?
  • ¿Sería frustrante reescribir esto cada vez que lo necesitara?
  • ¿Se podría aumentar la versatilidad del método con el uso de algunos parámetros?

Si alguno de los anteriores es cierto, debe estar envuelto en su propio método.


Hablando en general (¡y como principiante esto significa siempre!) Nunca debes hacer micro-optimizaciones como la que estás considerando. Siempre a favor de la legibilidad del código sobre cosas como esta.

¿Por qué? Porque el compilador / hotspot hará este tipo de optimizaciones para usted sobre la marcha, y muchas, muchas más. En todo caso, cuando intente realizar optimizaciones a lo largo de este tipo de líneas (aunque no en este caso), probablemente disminuirá la velocidad. Hotspot entiende expresiones de programación comunes, si intenta hacer esa optimización usted mismo probablemente no comprenda lo que está tratando de hacer para que no pueda optimizarla.

También hay un costo de mantenimiento mucho mayor. Si comienzas a repetir el código, será mucho más difícil mantenerlo, ¡lo que probablemente será mucho más complicado de lo que crees!

Por otro lado, puede llegar a algunos puntos en su vida de codificación donde necesita hacer optimizaciones de bajo nivel, pero si alcanza esos puntos, definitivamente, definitivamente sabrá cuando llegue el momento. Y si no lo hace, siempre puede regresar y optimizar luego si es necesario.


La mejor práctica es medir dos veces y cortar una vez.

Una vez que haya perdido la optimización del tiempo, ¡nunca más podrá recuperarla! (Así que mídelo primero y pregúntese si vale la pena optimizarlo. ¿Cuánto tiempo ahorrará?)

En este caso, Java VM probablemente ya esté haciendo la optimización de la que está hablando.


La optimización de los compiladores generalmente hace un buen trabajo eliminando la redundancia de estas operaciones "extra"; en muchos casos, la diferencia entre el código "optimizado" y el código simplemente escrito de la manera que desea, y ejecutar a través de un compilador optimizado es ninguno; es decir, el compilador de optimización generalmente hace un trabajo tan bueno como lo haría, y lo hace sin causar ninguna degradación del código fuente. De hecho, muchas veces, el código "optimizado para la mano" termina siendo MENOS eficiente, porque el compilador considera muchas cosas al hacer la optimización. Deje su código en un formato legible y no se preocupe por la optimización hasta más adelante.

"La optimización temprana es la raíz de todo mal." - Donald Knuth


Lo que todos los demás han dicho sobre la optimización es absolutamente cierto.

No hay ninguna razón desde el punto de vista del rendimiento para alinear el método. Si se trata de un problema de rendimiento, el JIT en su JVM lo alineará. En Java, las llamadas a métodos están tan cerca de ser libres que no vale la pena pensar en ello.

Dicho esto, hay un problema diferente aquí. A saber, es una mala práctica de programación llamar un método anulable (es decir, uno que no sea final , static o private ) del constructor. (Effective Java, 2nd Ed., P.89 en el ítem titulado "Design and document for inheritance or prohibit it")

¿Qué sucede si alguien agrega una subclase de BinarySearchTree llamada LoggingBinarySearchTree que anula todos los métodos públicos con un código como:

public void clear(){ this.callLog.addCall("clear"); super.clear(); }

¡Entonces el LoggingBinarySearchTree nunca será construible! El problema es que this.callLog será null cuando el constructor BinarySearchTree está ejecutando, pero el clear que se llama es el reemplazado, y obtendrá una NullPointerException .

Tenga en cuenta que Java y C ++ difieren aquí: en C ++, un constructor de superclase que llama a un método virtual termina llamando al definido en la superclase, no el invalidado. Las personas que cambian entre los dos idiomas a veces olvidan esto.

Dado que, en su caso, es probable que sea más limpio encuadrar el método clear cuando lo llama el constructor , pero en general en Java debe continuar y realizar todas las llamadas a los métodos que desee.


Mantenga el método clear() cuando ayuda a la legibilidad. Tener un código que no se puede mantener es más caro.


No me preocuparía tanto la llamada al método, sino la lógica del método. Si se tratara de sistemas críticos, y el sistema necesita "ser rápido" entonces, me gustaría optimizar los códigos que lleva mucho tiempo ejecutar.