Search code examples
javascriptperformancecanvasparticles

reason behind javascript particle performance in great number compare to other software and programs


Hello I'm new to programming and I made a simple JavaScript that draws simple canvas.arc circles that moves in 2D x,y-coordinates.

and just out of curiosity I ran the animation with 1 particle 10, 100, 1000 and so on and on increasing the number of the particles.

What I observed was particles moving smoothly up to few hundreds but then it becomes very laggy* (sorry I don't know the right term for this phenomenon)

and I was thinking, how can my computer run games and software that are far more complicated so smoothly yet struggles to run simple script I made with difficulty?

I'd like to know the reason behind this or theory behind it!

ps sorry I'm not confident with my English anyway please do post sources or other links that may help me understand this question.

This is the code. Its very simple but if there is way to improve performance please do tell me id like to know for future scripting.

Try increasing the particle count:

var particleCount = 10000;


window.requestAnimFrame = (function(){
  return window.requestAnimationFrame ||
  function(callback){
    window.setTimeOut(callback,1000/60);
  };
})();

var particleCount = 100,
    particles = [];

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var wW = window.innerWidth, wH =  window.innerHeight;

canvas.width = wW;
canvas.height = wH;


function paintCanvas(){
  ctx.fillStyle = "rgba(0,0,0,1)";
  ctx.fillRect(0,0,wW,wH);

}

function Particle(){
  this.x = Math.random() * wW;
  this.y = Math.random() * wH;

  var numx = Math.random()*2;
  var numy = Math.random()*2;

  numx *= Math.floor(Math.random()*2) == 1 ? 1 : -1;
  numy *= Math.floor(Math.random()*2) == 1 ? 1 : -1;

  this.vx = numx;
  this.vy = numy;

  this.radius = Math.random() * (Math.random()*5);
  this.draw = function(){
    ctx.fillStyle = "white";
    ctx.beginPath();
    ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,false);

    ctx.fill();
  }
}

for (var i=0; i<particleCount; i++){
  particles.push(new Particle());
}

function draw(){
  paintCanvas();

  for(var i = 0; i < particleCount; i++){
    p = particles[i];
    p.draw();
  }

  update();

}

function update(){
  for (var i =0; i < particleCount; i++){
    p = particles[i];

    p.x += p.vx;
    p.y += p.vy;

    if(p.x + p.radius > wW){
      p.x = p.radius;
    }
    else if(p.x - p.radius < 0){
      p.x = wW - p.radius;
    }

    if(p.y + p.radius > wH){
      p.y = p.radius;
    }
    else if(p.y - p.radius < 0){
      p.y = wH - p.radius;
    }


  }
}

function animloop(){
  draw();
  requestAnimFrame(animloop);
}

animloop();

As Fiddle: https://jsfiddle.net/b8xbv7fu/


Solution

  • Javascript is slow

    This is the nature of javascript and not the fault of your code. Javascript is a high level interpreted language. High level means is is heavily abstracted using objects and structures that are not understood directly by the CPU and thus requires extra work to do some of the more basic things. Interpreted means that to execute instructions there is a program that interprets each instruction and then calls special inbuilt (native) functions to run the logic of the program. This also incurs an overhead.

    When you compare Javascript to a language like C++ you can not compete. C++ is a compiled medium to low level language. Compiled means that before it can run its code is converted into machine language or Opcodes an intrum portable machine language that is assembled as it is loaded by the operating system. Machine language is basically a set of instructions that the CPU understands and can execute directly without the need of additional code.

    It gives the programmer a lower level of abstraction, some say harder to code, that is better suited to the design of the CPU. Additionally the compiler can take advantage of specific hardware such as CPU registers (VERY very fast variables). Concurrency (CPUs have two logic devices one for Floating point and one for integer arithmetic FPALU and ALU (Arithmetic logic unit)) If you are adding numbers and some are floating point and some integers and if you write carefully the compiler will ensure that as many of these operations are done at the same time. There are a host of other features that C++ and similar languages can take advantage of that Javascript can not. (Direct access to hardware, ability to be multi threaded, direct memory access and use of special memory instructions that can move large amounts of data quickly.

    Compiled low level languages are call native because the code is understood by the CPU, while Javascript must interpret each instruction each time it is needed for it to be able to run.

    Javascript at its best (Using a subset of the language commonly referred to as ASM.js) is one tenth the speed of a compiled language. Javascript will never compete with languages like C/C++

    There is also the lowest level language, Assembly Language in which you write specifically for one type of CPU using only the instructions the CPU can use. There is almost no abstraction and when well written is 2 or more times faster than C/C++.

    Javascript is a great place to start learning

    Learning Javascript is a good start, and the skills you learn with it can be transferred to any of the other languages. JavaScript has come a long way. 10 years ago 1000 object animated would be unheard of in JS now you can write reasonable 2D and 3D games.

    The lag you refer to is due to the drop in frame rate. Javascript will run at 60 frames a second if it can. If you give it to much work it will be forced to skip a frame. This results is a varying frame rate and what appears as jittery or jerky animations. There are ways to compensate.

    When writing games for JS it is important to become very familiar with how JS works, what is slow and what is quick. Saddly the general rule is that the easier the code is to write the slower the result. Being clever in your design is also important by doing only what is required (ie do not process object physics when it is off the screen, and pre computing data rather than as it is needed, do you really need 1000 object or will 100 images with 10 pre drawn particles get a similar effect)

    Javascript is a great language, expressive, forgiving and very portable. But with that you must accept its shortcomings (namely its is slow). If you wish to write high performance games you are best to learn C++