generated at
JS Nativeのsleep関数ほしい
from ES2025
promise実装版より正確に制御できるsleep関数実装してくれMijinko_SD
(あんまり正確に制御できてしまうとユーザーのトラッキングに転用できてしまう問題があるかもだけど)
そもそもC言語のsleep関数でもシステムコール呼んだりとかでオーバーヘッドあるしプロセスの切り替え間隔があるから無理ではbsahd
sleep前後でDate.now()して比較すればオーバーヘッドにかかった時間はわかる
js
function sleep(delay) { return new Promise((resolve, _) => { setTimeout(resolve, delay); }); } const iter = new Array(1000).fill(1); const a = performance.now(); function pump() { const a = iter.shift() if(typeof a == "undefined"){ return; } return sleep(0).then(pump); } pump().then(()=>{ console.log(performance.now() - a) })
パフォーマンスを測る際はDate.now()よりperformance.now()の方が良いMijinko_SD
以前個人的に測った際は sleep(0) でも20ms~50msぐらいの遅延が発生していた(Node.jsで計測した場合)
1000回sleepを呼び出して1662~2071msbsahd
というかGCがある原理上完全に無理bsahd
既に読み込み済みの単一プロセスの処理を一定時間止めるのにそこまで遅延が発生する想像がつかないけど・・・Mijinko_SD
まあそういうものなんだろうな🤔
promiseは別プロセスに分離しているので遅延が発生するのは仕方がない
プロセスではないのではbsahd
プロセス生成だとすると早すぎる
スレッドすら作らずにマイクロタスクで擬似スレッドしてたのでは
別スレッドかなんかだったかもしれないけれど忘れたMijinko_SD
何かしら別のタスクを生成していた記憶はある
そのあたりはググって
promiseが嫌なら同期版もあるよbsahd
js
function sleep(delay) { const before = performance.now(); while (performance.now() < before + delay) { // empty } } const iter = new Array(1000).fill(1); const a = performance.now(); for (const _ of iter) { sleep(1); } console.log(performance.now() - a);
強引で草Mijinko_SD
めちゃくちゃな回数performance.now()呼ばれている気がするけれど、パフォーマンス的に問題ないのかな?
パフォーマンス的に問題がないなら、精度もいいし使えそう
あ、ちなみに他の処理(レンダリング含む)を全てブロックするし、CPU利用率も結構上がるbsahd
参考として通常のsetTimeout版も入れておくbsahd
js
const iter = new Array(1000).fill(1); const a = performance.now(); function pump() { return new Promise((resolve, reject) => { const a = iter.shift(); if (typeof a == "undefined") { resolve() } setTimeout(() => { resolve(pump()); }, 0); }); } pump().then(() => { console.log(performance.now() - a); });
1000回setTimeoutを呼び出して1662~2071ms

身も蓋もないことをいうと、そんなに正確に待機する関数が必要な場面って、JS系であるのかな?takker
これは実際そうなんだよな、JavaScript使うときで正確に秒数指定で待機したいケースに出会ったことがないから必要性を感じない綾坂こと
科学計算系ならRust/Fortran/C++/Pythonを使おうという話になりそう
Pythonは科学計算には速度的には非力だった気がするbsahd