为什么 node.js 比 Google Chrome 慢很多?
Why node.js is much slower than Google Chrome?
我有简单的代码,它创建了一个块,其中包含 16*16*256 个框,每个框包含 10 个元素数组和一个 bool 变量。方法 tick 增加数组元素并更改块中每个框的布尔值 100 次。
通过测量时间我得到了结果:
Windows x64 node.js 7.4.0:
1 点:102.85
总时间(100):10285
Google Chrome 同一台机器上55个:
1 个刻度:18.08
总时间(100): 1808
甚至底层代码片段也比节点快一个数量级。
片段:
1 个刻度:22.79
总时间(100): 2279
那么,如何让 Node 运行得更快?
(function(){
class Box {
constructor() {
this.data = new Array(10);
this.state = false;
}
tick() {
this.state = !this.state;
for(let i = 0; i < this.data.length; i++) {
this.data[i]++;
}
}
}
class Chunk {
constructor() {
this.data = new Array(256);
for(let z = 0; z < this.data.length; z++) {
this.data[z] = new Array(16);
for(let x = 0; x < this.data[z].length; x++) {
this.data[z][x] = new Array(16);
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y] = new Box();
}
}
}
}
tick() {
for(let z = 0; z < this.data.length; z++) {
for(let x = 0; x < this.data[z].length; x++) {
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y].tick();
}
}
}
}
}
var c = new Chunk();
var count = 100;
var start = new Date().getTime();
for(let i = 0; i < count; i++) {
c.tick();
}
var end = new Date().getTime();
console.log("1 tick: " + (end - start) / count);
console.log("Total time(" + count + "): " + (end - start));
})();
预填充数组在节点中提供了一个数量级的改进
我能给出的唯一解释是空数组槽的 "conversion" 到 "used" 槽在 nodejs 中更昂贵 - 你可能会发现类似的加速 "filling" 原始代码中从 length-1 到 0 的数组(不多但很接近)
主要加速是在 class 框中预填充 this.data(但这可能是因为 empty
数组项上的 this.data[i]++
使用了 655360 次)
(function(){
class Box {
constructor() {
this.data = new Array(10).fill(0);
this.state = false;
}
tick() {
this.state = !this.state;
for(let i = 0; i < this.data.length; i++) {
this.data[i]++;
}
}
}
class Chunk {
constructor() {
this.data = new Array(256).fill(null);
for(let z = 0; z < this.data.length; z++) {
this.data[z] = new Array(16).fill(null);
for(let x = 0; x < this.data[z].length; x++) {
this.data[z][x] = new Array(16).fill(null);
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y] = new Box();
}
}
}
}
tick() {
for(let z = 0; z < this.data.length; z++) {
for(let x = 0; x < this.data[z].length; x++) {
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y].tick();
}
}
}
}
}
var c = new Chunk();
var count = 100;
var start = new Date().getTime();
for(let i = 0; i < count; i++) {
c.tick();
}
var end = new Date().getTime();
console.log("1 tick: " + (end - start) / count);
console.log("Total time(" + count + "): " + (end - start));
})();
as an aside, your Chunk constructor can be "simplified" to
this.data = new Array(256).fill([]).map(item => new Array(16).fill([]).map(item => new Array(16).fill([]).map(item => new Box())));
但这并没有使任何进一步的改善
我也尝试在适当的地方使用 .forEach
and/or .map
- 但任何此类更改实际上都会使节点
中的滴答减慢约 10%
我有简单的代码,它创建了一个块,其中包含 16*16*256 个框,每个框包含 10 个元素数组和一个 bool 变量。方法 tick 增加数组元素并更改块中每个框的布尔值 100 次。
通过测量时间我得到了结果:
Windows x64 node.js 7.4.0:
1 点:102.85
总时间(100):10285
Google Chrome 同一台机器上55个:
1 个刻度:18.08
总时间(100): 1808
甚至底层代码片段也比节点快一个数量级。
片段:
1 个刻度:22.79
总时间(100): 2279
那么,如何让 Node 运行得更快?
(function(){
class Box {
constructor() {
this.data = new Array(10);
this.state = false;
}
tick() {
this.state = !this.state;
for(let i = 0; i < this.data.length; i++) {
this.data[i]++;
}
}
}
class Chunk {
constructor() {
this.data = new Array(256);
for(let z = 0; z < this.data.length; z++) {
this.data[z] = new Array(16);
for(let x = 0; x < this.data[z].length; x++) {
this.data[z][x] = new Array(16);
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y] = new Box();
}
}
}
}
tick() {
for(let z = 0; z < this.data.length; z++) {
for(let x = 0; x < this.data[z].length; x++) {
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y].tick();
}
}
}
}
}
var c = new Chunk();
var count = 100;
var start = new Date().getTime();
for(let i = 0; i < count; i++) {
c.tick();
}
var end = new Date().getTime();
console.log("1 tick: " + (end - start) / count);
console.log("Total time(" + count + "): " + (end - start));
})();
预填充数组在节点中提供了一个数量级的改进
我能给出的唯一解释是空数组槽的 "conversion" 到 "used" 槽在 nodejs 中更昂贵 - 你可能会发现类似的加速 "filling" 原始代码中从 length-1 到 0 的数组(不多但很接近)
主要加速是在 class 框中预填充 this.data(但这可能是因为 empty
数组项上的 this.data[i]++
使用了 655360 次)
(function(){
class Box {
constructor() {
this.data = new Array(10).fill(0);
this.state = false;
}
tick() {
this.state = !this.state;
for(let i = 0; i < this.data.length; i++) {
this.data[i]++;
}
}
}
class Chunk {
constructor() {
this.data = new Array(256).fill(null);
for(let z = 0; z < this.data.length; z++) {
this.data[z] = new Array(16).fill(null);
for(let x = 0; x < this.data[z].length; x++) {
this.data[z][x] = new Array(16).fill(null);
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y] = new Box();
}
}
}
}
tick() {
for(let z = 0; z < this.data.length; z++) {
for(let x = 0; x < this.data[z].length; x++) {
for(let y = 0; y < this.data[z][x].length; y++) {
this.data[z][x][y].tick();
}
}
}
}
}
var c = new Chunk();
var count = 100;
var start = new Date().getTime();
for(let i = 0; i < count; i++) {
c.tick();
}
var end = new Date().getTime();
console.log("1 tick: " + (end - start) / count);
console.log("Total time(" + count + "): " + (end - start));
})();
as an aside, your Chunk constructor can be "simplified" to
this.data = new Array(256).fill([]).map(item => new Array(16).fill([]).map(item => new Array(16).fill([]).map(item => new Box())));
但这并没有使任何进一步的改善
我也尝试在适当的地方使用 .forEach
and/or .map
- 但任何此类更改实际上都会使节点