three.js 中使用多线程以及性能测试
今天郭先生说一下WebWorker以及WebWorker在three.js中的应用。我们都知道Javascript是单线程的,比如执行js代码的同时UI渲染就会停止,对于多核CPU的点脑,这一点让人难以接受,好在Web Worker的出现多少解决了一些问题。官方说Web Worker指的是一种可由脚本创建的后台任务,任务执行中可以向其创建者收发信息。要创建一个 Worker ,只须调用 Worker(URL) 构造函数,函数参数 URL
为指定的脚本。关于Web Worker的更多知识请阅读Web Worker。线案例请点击博客原文。
1. 在three.js中使用多线程
在three.js中使用Web Worker经常发生在大量计算造成CUP阻塞的情况下,我们举一个例子,比如说我们制作了1000个Mesh。
让他们简单的动起来,CPU几乎没有什么压力,FPS会在60左右,但是如果让这1000个Mesh的位置都需要大量计算才能得到,那么FPS就会很低(和计算量成负相关),下面是一段代码
for(let i=0; i<num; i++) {
let angle = positions[i].y / (1000 / (Math.PI * 10));
positions[i].x = positions[i].x + Math.sin(angle);
positions[i].z = positions[i].z + Math.cos(angle);
positions[i].y = positions[i].y + 1;
//上面就是简单的位置变化,下面的代码模拟复杂的变化,累加100000次(这是非常占用线程的情况)
for(let j=1, total=1; j<=100000; j++) {
total += j;
}
if(positions[i].y > 500) {
positions[i].y = positions[i].y - 1000;
}
}
for(var i=0; i<num; i++) {
group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
}
positions是储存1000个Mesh位置信息的数组,group里面储存了所有的Mesh,每次渲染都更改positions的位置信息,然后给Group的每一个Mesh设置新值,这种情况下FPS会低至7FPS,转动场景可以很明显的感觉到卡顿。接下来我们使用Web Worker处理这个问题,主线程代码如下
myWorker = new Worker('/static/js/worker.js');
myWorker.postMessage(positions);
myWorker.onmessage = e => {
let positions = e.data;
for(var i=0; i<num; i++) {
group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
}
}
脚本代码如下
onmessage = function(e) {
let num = 1000;
let positions = e.data;
setInterval(e => {
for(let i=0; i<num; i++) {
let angle = positions[i].y / (1000 / (Math.PI * 10));
positions[i].x = positions[i].x + Math.sin(angle);
positions[i].z = positions[i].z + Math.cos(angle);
positions[i].y = positions[i].y + 1;
for(let j=1, total=1; j<=100000; j++) {
total += j;
}
if(positions[i].y > 500) {
positions[i].y = positions[i].y - 1000;
}
}
postMessage(positions);
}, 1000 / 60)
};
主要代码和未使用Web Worker几乎一样,只不过是将处理位置的代码放在新的线程中完成,setInterval定时器每一次完成位置计算都会通过postMessage(positions)将位置信息返回给主线程,主线程通过onmessage接受信息,返回对象的data属性就是新的positions。这样一来FPS可以达到60左右,转动场景感觉的到卡顿。这是十分让人欣喜的。
2. 性能分析
前面已经说了在每一次位置计算中做10万次累加,未使用Web Worker的情况下FPS降到了7,下面是更多的数据(数据仅做对比,和当前使用情况以及配合有关)。
累加次数(万次) | 使用Web Worker | 未使用Web Worker |
1 | 60 | 60 |
3 | 60 | 39 |
5 | 60 | 26 |
7 | 60 | 11 |
9 | 60 | 8 |
11 | 60 | 6 |
这里面可以看出,不管是多么大量的计算,使用Web Worker都不会影响主线程,但是对于未使用Web Worker影响是十分严重的,下面展示一下两种情况下电脑性能的对比
下面是未使用Web Worker
下面是使用Web Worker
这里可以看出使用更多的线程可以很明显的提升CPU使用率。小伙伴们不妨打开线上案例亲自测试一下。
转载请注明地址:郭先生的博客
three.js 中使用多线程以及性能测试的更多相关文章
- 【worker】js中的多线程
因为下个项目中要用到一些倒计时的功能,所以就提前准备了一下,省的到时候出现一下界面不友好和一些其他的事情.正好趁着这个机会也加深一下html5中的多线程worker的用法和理解. Worker简介 J ...
- JS中的异步以及事件轮询机制
一.JS为何是单线程的? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊.(在JAVA和c#中的异步 ...
- Web worker 与JS中异步编程的对比
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...
- 【面试篇】寒冬求职季之你必须要懂的原生JS(中)
互联网寒冬之际,各大公司都缩减了HC,甚至是采取了“裁员”措施,在这样的大环境之下,想要获得一份更好的工作,必然需要付出更多的努力. 一年前,也许你搞清楚闭包,this,原型链,就能获得认可.但是现在 ...
- js中的异步与同步,解决由异步引起的问题
之前在项目中遇到过好多次因为异步引起的变量没有值,所以意识到了认识js中同步与异步机制的重要性 在单线程的js中,异步代码会被放入一个事件队列,等到所有其他代码执行后再执行,而不会阻塞线程. 下面是j ...
- 关于js中的回调函数callback
来源于:http://www.jianshu.com/p/6bc353e5f7a3 前言 其实我一直很困惑关于js 中的callback,困惑的原因是,学习中这块看的资料少,但是平时又经常见,偶尔复制 ...
- 关于 js 中的回调函数 callback
本文写于1年前 曾经的学习文章如今拿出来分享 前言 其实我一直很困惑关于js中的callback,困惑的原因是,学习中这块看的资料少,但是平时又经常见,偶尔复制一下前人代码,功能实现了也就不再去追其原 ...
- 疯狂Html+CSS+JS 中JS总结
来自:http://mzkmzk.github.io/blog/2015/10/05/amazeing-js/ 0 总结 本书的JS 第一章有讲语法有挺多常见的坑点和原理解释很不错 第二章DOM编程讲 ...
- js中的webworker
js中的webworker webworker的作用类似于java的多线程 以独立文件的形式运行webworker index.html <!DOCTYPE html> <html ...
随机推荐
- Linux 挂载,卸载光盘
首先我们点击虚拟机 点击设置 选择CD 接着我们将设备状态两个勾都勾选,并且ISO映像文件选择我们需要挂载的光盘 点击了确定之后,我们到centos7的命令行下 1,创建挂载目录 mkdir /mnt ...
- DVWA SQL Injection LOW
最近在学习SQL注入,初出茅庐,就从dvwa开始吧 sql注入可以通过sqlmap工具实现,为了更好地了解原理,这里主要是手工注入 注入的一般流程为: 1,找到注入点,此步骤可通过工具 2,判断注入类 ...
- 团队作业3_需求改进&系统设计
一.需求&原型改进 1.需求改进: (1)发现问题:通过发布问卷调查及收集整理的形式发现用户的新需求: (2)修改需求:考虑新增提醒用户未完成事件的功能. 附:用户调查问卷(如下) 调研途 ...
- 2020中国.NET开发者峰会主题内容发布
2020年12月09日,组委会正式发布了China .NET Conf 2020中国 .NET 开发者峰会的主题内容. 今年的大会主题收到超预期的主题,无论是数量还是质量上都比2019年有所进步,这也 ...
- 【自用】Notice
读题 不要把 \(\sum a \oplus b\) 看成异或和. 注意读完整,有可能对原有符号有新的约定,不要想当然. 注意模数的 0 数清楚. 卡常&时间 打题之前一般先搞个自己的缺省源. ...
- 开始是为了结束,结束是新的开始——NOI 2020 游记
Day 0 报道日 晚上的时候我们的教练给我们做考前动员.给我们讲:NOI的五个小时需要认真的规划,不能被T1打乱节奏.他让我们思考明天的策略,把可能出问题的地方都想清楚. 结果后来,宿管给我测体温, ...
- Robot Framework+adb框架自动化测试Android设备案例⑷——L2层关键字
一.EMMC测试套件 L2层关键字.robot *** Settings *** Resource ../L3公共层.robot *** Keywords *** 一般录影文件列表(EMMC) ${f ...
- git学习——git下载安装
原文来至 一.集中式vs分布式 Linus一直痛恨的CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢? 先说集中式版本控制系统,版本库是集中 ...
- Robot Framework+adb框架自动化测试Android设备案例⑹——源码地址、测试报告
一.源码地址 GitHub:https://github.com/xiongye105554598/DVR8010_AutoTest 二.测试报告
- STL——容器(List)list 的赋值操作
list.assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身 1 #include <iostream> 2 #include <list> ...