gpt4 book ai didi

javascript - 如何最大化异步调度程序的性能?

转载 作者:行者123 更新时间:2023-12-03 06:21:47 24 4
gpt4 key购买 nike

我注意到 JavaScript 中有一种奇怪的技术,我用它来提高在 Canvas 上绘制的重复过程的性能。将来,我计划在实现时使用 SharedBuffer 甚至 SharedCanvas,但与此同时,这是我使用的总体思路:

function someContinuousProcess(intervals, delay) {
var count = 0;
var span = document.querySelector('span');

function someExpensiveFunction() {
if (count >= 1e9) {
return false;
}

do {
count++;
} while (count % 1e5);

span.textContent = count;

return true;
}

function wrapper(index) {
var start = performance.now();

if (someExpensiveFunction()) {
var delta = performance.now() - start;
// some logic here to determine new
// values for `intervals` and `delay`
scheduler[index] = setTimeout(
wrapper.bind(null, index),
delay
);
}
}

var scheduler = [];

function startScheduler() {
for (var i = 0; i < intervals; i++) {
scheduler[i] = setTimeout(
wrapper.bind(null, i),
delay
);
}
}

function stopScheduler() {
for (var i = 0; i < scheduler.length; i++) {
clearTimeout(scheduler[i]);
}

scheduler = [];
}

startScheduler();
}

int.onchange = del.onchange = () => {
var intervals = parseInt(int.value);
var delay = parseInt(del.value);

if (!isNaN(intervals) && !isNaN(delay)) {
someContinuousProcess(intervals, delay);
}
};
<input placeholder=intervals id=int>
<input placeholder=delay id=del>
<span></span>

如果你搞乱这些参数,你会发现当然延迟间隔都会对性能产生显着的影响。但在某种程度上,如果您为某个延迟设置太多间隔,性能增益将变成性能下降,同时导致线程无响应。

我的问题是,是否可以根据给定的someExpectiveFunction自适应地选择间隔延迟?假设我们可以让 someExpectiveFunction() 返回高分辨率时间戳 performance.now(),那么我们如何使用它来改变间隔 并智能地延迟以优化性能?

最佳答案

这似乎是使用网络 worker 的绝佳机会。它们在单独的线程中执行,因此不会影响主线程上的动画。

但是,仍然要求您不要过于频繁地postMessage,否则主线程中的事件循环会因消息数量过多而阻塞。

function simple() {
var span = $('#v1');
var worker = new Worker('data:text/javascript;charset=UTF-8,' + encodeURI($('#someExpensiveFunction').text()));

worker.onmessage = progress => span.text(progress.data);
worker.onerror = x => {
debugger;
};
}

function withanim() {
var span = $('#v2');
var worker = new Worker('data:text/javascript;charset=UTF-8,' + encodeURI($('#someExpensiveFunction').text()));

var latestMessage = 0;
worker.onmessage = progress => latestMessage = progress.data;
worker.onerror = x => {
debugger;
};

var myReq;
function step(timestamp) {
span.text(latestMessage);
if (latestMessage < 1e9)
myReq = requestAnimationFrame(step);
}
myReq = requestAnimationFrame(step);
}

simple();
withanim();
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js" 
type="text/javascript" charset="utf-8"></script>
<div id=v1></div>
<div id=v2></div>
<script type="text/worker" id="someExpensiveFunction">
var count = 0;
var start = performance.now();
var reportPerSec = 100; //change this
var delay = 1000/reportPerSec;
do {
//some un-interrupable task
//it might be useful to put this in a setTimeout(0), if you also want to use onmessage to get data to work on from the main thread
do {
count++;
} while (count % 1e2);

//report progress
if (performance.now() - start > delay) {
postMessage(count);
start = performance.now();
}
} while (count < 1e9);
postMessage(count); //make sure to send 'done'
</script>

Fiddle

关于javascript - 如何最大化异步调度程序的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38834571/

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