es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problemas de rendimiento al instanciar clases que contienen variables definidas.

He notado un comportamiento extraño en JavaScript cuando se instancia una clase con variables definidas.

Nota: el código a continuación simplemente sirve como un caso de reproducción para este problema específico.

Consideremos la siguiente clase:

class Vector3
{
    #unused1;
    #unused2;
    #unused3;
    #unused4;
    #unused5;
    #unused6;
    #unused7;
    #unused8;
    #unused9;
    #unused10;
    #unused11;
    #unused12;
    #unused13;

<pre><code>constructor(x, y, z)
{
    this.x = x;
    this.y = y;
    this.z = z;
}
</code></pre>

<p>}
<code>
Y el siguiente script:
</code>javascript
let frames = 0;
let p = 0;
let fn = () => {</p>

<pre><code>let now = performance.now();
let sum;
for (let i = 0; i < 10000; i++)
{
    var vector = new Vector3(Math.random(),Math.random(),Math.random());
    var o = new Vector3(vector.x + Math.random(), vector.y + Math.random(), vector.z + Math.random());
}

// revisar la cantidad de frames pasados cada segundo
if (now - p >= 1000) {
    console.log(frames);
    // agregado para probar el rendimiento sin tener abiertas las herramientas de desarrollo
    document.documentElement.innerText = frames;
    frames = 0;
    p = now;
}

frames++;

requestAnimationFrame(() => {
    return fn();
})
return;
</code></pre>

<p>}
fn();

Al ejecutar lo anterior y ver la consola, podemos ver que el rendimiento está alrededor de (dependiendo de tus especificaciones), 30 a 35 frames.

Ahora, si modificamos la clase para no contener variables definidas de la siguiente manera:
javascript
class Vector3
{
constructor(x, y, z)
{
this.x = x;
this.y = y;
this.z = z;
}
}

Podemos ver que el rendimiento aumenta a (nuevamente, dependiendo de tus especificaciones) 60 frames y más.

Al principio pensé que este problema tenía que ver con la recolección de basura, pero después de revisar el Chrome Profiler, me di cuenta de que la mayor parte del rendimiento estaba siendo afectado por la obtención de variables y después de investigar y realizar más pruebas, noté que este problema en realidad no tenía que ver con las variables en uso, sino con las variables declaradas.

También es importante tener en cuenta que no parece “importar” si la variable se declara como privada o pública.

¿Alguien tiene una explicación de por qué ocurre este problema?

Actualización: este problema parece afectar más a Chromium que a Firefox. Firefox siempre parece llegar a 60.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema observado parece estar relacionado con la sobrecarga creada por la definición de clase y sus campos privados no utilizados. Cuando la definición de clase contiene variables definidas no utilizadas, el rendimiento de la instantiación de la clase se reduce significativamente, ya que el motor de JavaScript necesita invertir más tiempo en configurar las estructuras de datos internas relacionadas con la definición de clase.

    Por otro lado, cuando la definición de clase no contiene ninguna variable definida no utilizada, la definición de clase es más ligera y el motor de JavaScript puede optimizar la creación e instantiación de objetos, lo que resulta en un mejor rendimiento.

    Una posible solución a este problema sería eliminar cualquier variable definida no utilizada de las definiciones de clase donde no sean necesarias. Esto permitirá que el motor de JavaScript optimice la definición de clase y proporcione un mejor rendimiento al instanciar objetos.

    También vale la pena señalar que este problema parece afectar más a Chromium que a Firefox, siendo Firefox consistentemente mejor en rendimiento en diferentes definiciones de clase.

Comments are closed.