gpt4 book ai didi

javascript - javascript 中循环和 CPS 循环的完全奇怪的性能

转载 作者:行者123 更新时间:2023-11-30 20:29:00 26 4
gpt4 key购买 nike

为了查看实现循环的延续传递样式是否太慢而无法在 javascript 中使用,我创建了一个 JS-Perf 来使用以下代码对此进行测试:

 const ITERATIONS = 10000;

function NormalLoop() {
for (var i = 0; i < ITERATIONS; i++) {
console.log("loop iteration");
if (i % 5) {
console.log("continuing");
i += 2;
continue;
}
console.log("normally going out");
}
console.log("ended loop");
}

function WhileTrueLoop() {
var i = 0;
while (true) {
if (i >= ITERATIONS) {
break;
}
console.log("loop iteration");
if (i % 5) {
console.log("continuing");
i += 2;
i++;
continue;
}
console.log("normally going out");
i++;
}
console.log("ended loop");
}

function NonTrampLoop() {
var i = 0;
n1(i);
}

function n1(i) {
if (i >= ITERATIONS) {
n4(i);
return;
}
console.log("loop iteration");
if (i % 5) {
console.log("continuing");
i += 2;
n3(i)
return;
}

n2(i)
}

function n2(i) {
console.log("normally going out");
n3(i);
}

function n3(i) {
i = i + 1;
n1(i);
}

function n4() {
console.log("ended loop");
}

function TrampolineSimplistic() {
var f = function () { return ts1(0) };
while (f !== null) { f = f(); }
console.log("ended loop");
}

function ts1(i) {
if (i >= ITERATIONS) {
return null;
}
console.log("loop iteration");
if (i % 5) {
console.log("continuing");
i += 2;
return function () { return ts3(i); };
}

return function () { return ts2(i); };
}

function ts2(i) {
console.log("normally going out");
return function () { return ts3(i); }
}

function ts3(i) {
i = i + 1;
return function () { return ts1(i); }
}

function TrampolineStreamlined() {

var f = { cont: t1, i: 0 };
while (f.cont !== null) { f.cont(f); }
console.log("ended loop");
}

function t1(th) {
var i = th.i;
if (i >= ITERATIONS) {
th.cont = null;
return;
}
console.log("loop iteration");
if (i % 5) {
i = i + 2;
th.i = i;
th.cont = t3;
return;
}

th.i = i;
th.cont = t2;
return;
}

function t2(th) {
var i = th.i;
console.log("normally going out");
th.i = i;
th.cont = t3;
return;
}

function t3(th) {
var i = th.i;
i = i + 1;
th.i = i;
th.cont = t1;
return;
}

这五种方法是使用标准的 for 循环、while-true 循环、使用简单的函数调用、使用 trampolining 和 CPS 以及使用 trampolining 和 CPS 在堆上预分配局部变量。

我预计 for 循环是最快的,紧随其后的是 while-true 循环,然后是蹦床循环比 for 循环长 2-10 倍,朴素函数循环比 for 循环长 10-100 倍-循环。

现在令人震惊的是,蹦床循环似乎在 Firefox 上执行得最快。最慢的循环似乎是 while-true 循环!即使是朴素的函数调用循环也相对较快。当朴素的函数循环根据迭代次数按比例增加堆栈,而其他方法使用恒定的堆栈空间时,这怎么可能。

此外,天真的蹦床循环在每次执行期间多次在堆上分配一个函数。 javascript 引擎是否在优化函数调用方面非常激进?我是否在我的代码中做了一些特别愚蠢的事情?

最佳答案

不是答案,但我在一些浏览器上运行了一些计时。时间以毫秒为单位,迭代次数取决于浏览器在堆栈大小出错之前的粗略最大大小。

Firefox
Iterations : 30000
NormalLoop : 0
WhileTrueLoop : 1
NonTrampLoop : 22
TrampSimplistic : 2
TrampStreamlined: 1

Chrome
Iterations : 14000
NormalLoop : 3
WhileTrueLoop : 2
NonTrampLoop : 1
TrampSimplistic : 7
TrampStreamlined: 3

Edge
Iterations : 5000
NormalLoop : 0
WhileTrueLoop : 1
NonTrampLoop : 3
TrampSimplistic : 11
TrampStreamlined: 3

Chrome
Iterations : 200000
NormalLoop : 4
WhileTrueLoop : 4
TrampSimplistic : 68
TrampStreamlined: 14

Firefox 中的时间非常一致,对于其他浏览器,结果各不相同,我使用了我认为最一致的输出。

关于javascript - javascript 中循环和 CPS 循环的完全奇怪的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50571171/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com