与其他软件和程序相比,JavaScript 粒子性能背后的原因

问题描述 投票:0回答:1

您好,我是编程新手,我编写了一个简单的 JavaScript,用于绘制在 2D x,y 坐标中移动的简单 canvas.arc 圆。

出于好奇,我用 1 个粒子 10、100、1000 等运行动画,并不断增加粒子数量。

我观察到粒子平滑地移动到数百个,但随后变得非常滞后*(抱歉,我不知道这种现象的正确术语)

我在想,我的电脑如何能够如此顺利地运行复杂得多的游戏和软件,却难以运行我艰难编写的简单脚本?

我想知道这背后的原因或背后的理论!

ps 抱歉,无论如何,我对自己的英语没有信心,请发布资源或其他链接来帮助我理解这个问题。

这是代码。它非常简单,但如果有方法可以提高性能,请告诉我我想知道以便将来编写脚本。

尝试增加粒子数:

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();

作为小提琴:https://jsfiddle.net/b8xbv7fu/

javascript performance canvas particles
1个回答
3
投票

Javascript 很慢

这是 javascript 的本质,而不是你的代码的错误。 Javascript 是一种高级解释语言。高级手段是使用 CPU 无法直接理解的对象和结构进行大量抽象,因此需要额外的工作来完成一些更基本的事情。解释意味着要执行指令,有一个程序解释每条指令,然后调用特殊的内置(本机)函数来运行程序的逻辑。这也会产生开销。

当你将 Javascript 与 C++ 这样的语言进行比较时,你无法与之竞争。 C++ 是一种编译型中低级语言。编译意味着在运行之前,其代码被转换为机器语言或操作码(一种可移植的机器语言),在操作系统加载时进行汇编。机器语言基本上是CPU可以理解并且可以直接执行而不需要额外代码的一组指令。

它为程序员提供了较低的抽象级别,有人说更难编码,但更适合 CPU 的设计。此外,编译器可以利用特定硬件,例如 CPU 寄存器(非常非常快的变量)。并发(CPU 有两种逻辑设备,一种用于浮点,一种用于整数算术 FPALU 和 ALU(算术逻辑单元))如果您要添加数字,其中一些是浮点,一些是整数,并且如果您仔细编写,编译器将确保尽可能多的这些操作是同时完成的。 C++ 和类似语言可以利用 JavaScript 无法利用的许多其他功能。 (直接访问硬件、多线程能力、直接内存访问以及使用可以快速移动大量数据的特殊内存指令。

编译的低级语言被称为本机语言,因为 CPU 可以理解代码,而 Javascript 必须在每次需要时解释每条指令才能运行。

Javascript(使用通常称为 ASM.js 的语言子集)的速度是编译语言的十分之一。 Javascript永远不会与C/C++这样的语言竞争

还有一种最低级语言,即汇编语言,您可以仅使用 CPU 可以使用的指令专门为一种类型的 CPU 编写代码。几乎没有抽象,如果写得好,速度比 C/C++ 快 2 倍或更多。

Javascript 是开始学习的好地方

学习 Javascript 是一个好的开始,你用它学到的技能可以转移到任何其他语言。 JavaScript 已经取得了长足的进步。 10 年前,1000 个对象动画在 JS 中是闻所未闻的,现在您可以编写合理的 2D 和 3D 游戏。

您提到的延迟是由于帧速率下降造成的。如果可以的话,Javascript 将以每秒 60 帧的速度运行。如果你给它太多的工作,它将被迫跳过一帧。结果是不同的帧速率以及出现的抖动或不稳定的动画。有办法弥补。

在为 JS 编写游戏时,非常熟悉 JS 的工作原理、什么是慢的、什么是快的非常重要。遗憾的是,一般规则是代码越容易编写,结果就越慢。聪明地设计也很重要,只做需要的事情(即,当物体离开屏幕时不处理物体物理,并且预先计算数据而不是在需要时计算数据,您真的需要 1000 个物体还是将 100 个图像与10 个预先绘制的粒子获得类似的效果)

Javascript 是一种很棒的语言,富有表现力、宽容且非常可移植。但随之而来的是你必须接受它的缺点(即它很慢)。如果你想编写高性能游戏,你最好学习 C++

© www.soinside.com 2019 - 2024. All rights reserved.