Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More readable JavaScript code is slower?

Tags:

I came across this small JavaScript Program (on Khan Academy) written by someone else:

/*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]);
    }
};

I looked at the code and found it a bit difficult to read. So I decided to make my own version with some object orientation:

// 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);
    }
};

The original just uses arrays for data. Index [0] is an x coordinate, index [1] is a y coordinate, index [2] is a flag. I think the only changes I made were just what was needed to replace point[0] with point.x, etc. but I was surprised by how much slower my version was.

Is there a better way to make the code more readable without losing performance? or do we have to lose performance for readability?

JavaScript Engine: Chrome in Windows 10

Edit: more information discovered:

As Ryan pointed out, using plain objects instead of a Point class – new Point(x, y){x: x, y: y, moving: false} - improved performance close to the original. So it was just the Point class that made it slow.

So now working with 3 different versions of the program:

  • array data ( original )
  • Point class ( 1st rewrite )
  • plain object ( 2nd rewrite )

In Chrome, the array data and plain object have no easily noticeable difference in performance, the Point class is noticeably slower.

I installed Firefox to test it, and found all three versions to be close to the same performance as each other.

Just eyeballing it, the Firefox speed seems to be in between the slow and the fast speeds I get from Chrome, probably closer to the fast end.

like image 832
beauxq Avatar asked Dec 25 '17 04:12

beauxq


People also ask

Is JavaScript readable?

JavaScript has been evolving into a more readable language. There is no doubt about that, and there is no harm either. Software development is a dynamic market where teams change constantly, meaning that the code needs to be readable for newcomers.


1 Answers

That is why people use bundlers like webpack to make readable code more efficient. Checkout https://webpack.js.org/

like image 122
Anthony Delgado Avatar answered Oct 25 '22 09:10

Anthony Delgado