practices - ¿El código JavaScript más legible es más lento?
javascript puro (3)
Me encontré con este pequeño programa de JavaScript (en Khan Academy) escrito por otra persona:
/*vars*/
frameRate(0);
var Sz=100;
var particles=1000;
scale(400/Sz);
var points=[[floor(Sz/2),floor(Sz/2),false]];
for(var i=0;i<particles;i++){
points.push([floor(random(0,Sz)),floor(random(0,Sz)),true]);
}
var l=points.length-1;
var dirs=[[0,1],[1,0],[0,-1],[-1,0]];
/*functions*/
var move=function(p1){
var mv=dirs[floor(random(0,4))];
var temp=true;
for(var i=l;i>=0;i--){
if(!points[i][2]&&points[i][0]===p1[0]+mv[0]&&points[i][1]===p1[1]+mv[1]){
temp=false;
p1[2]=false;
i=0;
}
}
if(temp){
p1[0]+=mv[0];
p1[1]+=mv[1];
if(p1[0]<0){p1[0]=0;}
if(p1[0]>Sz){p1[0]=Sz;}
if(p1[1]<0){p1[1]=0;}
if(p1[1]>Sz){p1[1]=Sz;}
}
};
/*draw*/
draw= function() {
background(255);
for(var i=points.length-1;i>=0;i--){
stroke(0);
if(points[i][2]){
move(points[i]);
}
else{
stroke(0,0,255);
}
point(points[i][0],points[i][1]);
}
};
Miré el código y me resultó un poco difícil de leer. Así que decidí hacer mi propia versión con alguna orientación a objetos :
// apparently, object orientation is a lot slower than just putting the data in arrays
var Point = function(x, y) {
this.x = x;
this.y = y;
this.moving = true;
};
// static constant
Point.dirs = [
{x:0, y:1},
{x:1, y:0},
{x:0, y:-1},
{x:-1, y:0}
];
/*vars*/
frameRate(0);
var Sz=100;
var particles=1000;
scale(400/Sz);
// first point
var points=[new Point(floor(Sz/2), floor(Sz/2))];
points[0].moving = false; // blue
// remaining points
for(var i=0;i<particles;i++){
points.push(new Point(floor(random(0, Sz)), floor(random(0, Sz))));
}
var l=points.length-1;
/*functions*/
var move = function(p1){
var mv = Point.dirs[floor(random(0,4))];
var notAttached = true;
for(var i = l; i >= 0; i--) {
if(!points[i].moving && points[i].x === p1.x + mv.x && points[i].y === p1.y + mv.y) {
notAttached = false;
p1.moving = false;
i = 0;
}
}
if (notAttached) {
p1.x += mv.x;
p1.y += mv.y;
if (p1.x < 0) { p1.x = 0; }
if (p1.x > Sz) { p1.x = Sz; }
if (p1.y < 0) { p1.y = 0; }
if (p1.y > Sz) { p1.y = Sz; }
}
};
/*draw*/
draw= function() {
background(255);
for(var i=points.length-1; i >= 0; i--) {
stroke(0);
if (points[i].moving) {
move(points[i]);
}
else {
stroke(0, 0, 255);
}
point(points[i].x, points[i].y);
}
};
El original solo usa matrices para datos. El índice [0]
es una coordenada x, el índice [1]
es una coordenada ay, el índice [2]
es una bandera. Creo que los únicos cambios que hice fueron los necesarios para reemplazar el point[0]
con point.x
, etc., pero me sorprendió lo mucho más lenta que era mi versión.
¿Hay una mejor manera de hacer que el código sea más legible sin perder rendimiento? ¿O tenemos que perder rendimiento para mejorar la legibilidad?
Motor de JavaScript: Chrome en Windows 10
Edición: más información descubierta:
Como señaló Ryan, usar objetos planos en lugar de una clase de Point
- new Point(x, y)
→ {x: x, y: y, moving: false}
- rendimiento mejorado cerca del original. Así que fue solo la clase Point
que lo hizo lento.
Así que ahora trabajamos con 3 versiones diferentes del programa:
- datos de matriz (original)
- Clase puntual (1ª reescritura)
- objeto plano (2da reescritura)
En Chrome, los datos de la matriz y el objeto simple no tienen una diferencia en el rendimiento fácilmente perceptible, la clase Point es notablemente más lenta.
Instalé Firefox para probarlo, y encontré que las tres versiones estaban cerca del mismo rendimiento que las otras.
Solo observándolo, la velocidad de Firefox parece estar entre la velocidad lenta y la velocidad rápida que recibo de Chrome, probablemente más cerca del extremo rápido.
Es por eso que las personas utilizan paquetes como webpack para hacer que el código legible sea más eficiente. Checkout https://webpack.js.org/
Seguro que no eres el único programador que ve / verá este código (probablemente, algunos de los programadores son principiantes, lo que será difícil incluso entender el código).
¡Para tu código elegiré legibilidad en lugar de rendimiento!
Me libraría de esto y de lo nuevo . ¿Es este el objeto global o indefinido? ¡No puedo decir de tu ejemplo! Tienes que saber en qué contexto estás.
La optimización prematura es la fuente de todos los males. Donald Knuth.
Los navegadores se han vuelto muy buenos optimizando el código que escribimos.
Puedes probar la velocidad de tu programa usando performance.now () que es bastante preciso:
var t1 = performance.now()
//your code
var t2 = performance.now()
console.log(t2-t1);
O puede usar jsperf ( https://jsperf.com/ ). Estoy seguro de que hay otros varios sitios web con este servicio.
Gran comentario de JLRishe: ¿El código JavaScript más legible es más lento? que estoy totalmente de acuerdo.
si el problema es solo con la velocidad de ejecución que intentar minimizar el archivo .js, ya que obviamente el código legible contiene más espacio intermedio, el tamaño del archivo también aumenta, por lo tanto, para el desarrollo, use el código legible y una vez que se complete el desarrollo, comprima el código y adjúntelo de su código sin comprimir.