0

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/

try-catch-finally
  • 7,436
  • 6
  • 46
  • 67
Paul
  • 39
  • 1
  • 8
  • Are you using `requestAnimationFrame` to prevent a redraw/repaint before your frame has been calculated? – Paul S. Dec 07 '15 at 04:44
  • Canvas can smoothly run many more than 200 objects so we'll need to see your perf code to give you a detailed answer. – markE Dec 07 '15 at 05:03
  • yes I'm using requestAnimationFrame my code is really simple. inside loop animation theres nothing much except drawing circles and moving them via update this.x or y += constant velocity ex.1 or 2. most codepen.io posts are same. they run smoothly until particle numbers are increased to 650 or over 1000. – Paul Dec 07 '15 at 05:15
  • http://jsfiddle.net/m1erickson/vnc752cg/ – markE Dec 07 '15 at 06:50
  • I went up to 5000 particles and i had a small stutter the first 1-2 seconds. After those it went smoothly, so the initial stutter can be caused by initialization. And the general "smoothness" can depend on ram/cpu available to the browser. So you might want to check those options. – dwana Dec 07 '15 at 12:08

1 Answers1

3

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++

Blindman67
  • 51,134
  • 11
  • 73
  • 136
  • While I agree with everything here, please don't forget that _JavaScript_ isn't just for beginners, EMCAScript is its own branch of language (prototypical **and** functional) so when you're advanced you can do things unlike any classical language. – Paul S. Dec 07 '15 at 15:26
  • @PaulS. There is nothing you can do in javascript that can not be done in any other language and via versa. Remember that most Javascript engines are written in C++, you could also implement it in Assembly. That is the nature of all turing complete languages, anyone can do anything anything any other can do. (prototypical and functional) are inbuilt abstractions and not the exclusive domain of Javascript. – Blindman67 Dec 07 '15 at 15:50
  • Fair enough ... you might also mention that Javascript is the most widely available language for web-based projects -- and availability is often traded for speed when designing a web-based deliverable. Anyway, since you're suggesting C++, what would you suggest as an alternate framework for web-based projects that supports C++? – markE Dec 07 '15 at 15:55
  • 1
    @markE Sorry As this is clearly an emotive subject I will simply say I have no stance for or against any language and simply answered the OP's question. – Blindman67 Dec 07 '15 at 16:21
  • @Blindman67 I don't mean it's impossible to do in other languages, I mean the other languages don't let you write things in certain ways; first class functions, prototypical inheritance, etc. This means you can write code in a different way to achieve the same goal. – Paul S. Dec 07 '15 at 17:01
  • Awesome! I didn't know about this till now that the other programming language like C++ can be compiled into more machine friendly. I guess there is more pros and cons to programming languages that I should know about. – Paul Dec 08 '15 at 02:15
  • Keep in mind JavaScript will be JIT compiled... so it isn't always hitting up the interpreter: see http://stackoverflow.com/questions/95635/what-does-a-just-in-time-jit-compiler-do – laughingpine Dec 23 '15 at 22:57