1

タスク スケジューリング (過剰) 使用に関して、アプリケーションが適切にスケーリングするために超えてはならない境界を定義することは可能ですか?

質問:

  1. setTimeout を実行するのに一定のコストはかかりますか? 0.1ミリ秒またはCPU時間としましょう。さまざまな環境でスレッドを生成するよりも、桁違いに低コストであることは確かです。しかし、ありますか?
  2. 1〜2ミリ秒かかるマイクロタスクには setTimout を使用しない方がよいですか?
  3. スケジューリングが嫌いなことはありますか?たとえば、ストアの取得などをスケジュールするときに、書き込みロックのためのある種の IndexedDb 飢餓に気付きました
  4. DOM 操作を安全にスケジュールできますか?

Scala.jsと大規模なスケジューリングを使用する Rx 実装Monifuを使い始めたので質問しています。1 行のコードで 5 つのタスクがイベント ループのキューに送信されることがあるので、基本的には、パフォーマンスを低下させるタスク キューのオーバーフローのようなものはありますか? 特に、毎秒数百のタスクがキューに入れられる可能性のあるテスト スイートを実行しているときに、この質問をしています。

別の質問につながるのは、RunNow/Trampoline スケジューラーを使用する必要があるケースと、Rx に関して Queue/Async スケジューラーを使用するケースをリストすることは可能ですか? obs.buffer(3).last.flatMap{..}複数のタスクをスケジュールするようなものを書くたびに、これについて疑問に思っています

4

1 に答える 1

1

Monifu でのスケジューリングに関する注意事項 - Monifu は非同期パイプラインを折りたたもうとするため、下流のオブザーバーが本質的に同期している場合、Monifu はタスクをスケジューラーに送信することを回避します。Monifu はバックプレッシャーも行うため、Scheduler に送信されるタスクの数を制御するため、ブラウザーのキューが爆発するような状況に陥ることはありません。

たとえば、このようなものObservable.range(0,1000).foldLeft(0)(_+_).map(_ + 10).filter(_ % 2 == 0)は、最初のループを開始するためにスケジューラで単一のタスクのみを送信しています。それ以外の場合、オブザーバーも同期的であり、そのキュー内の他のタスクを送信しない場合、パイプライン全体が完全に同期的です。そして、そのソースがどれくらい大きくなるかわからないため、キューの最初のタスクを送信します。通常、データソースへのサブスクライブは、ブロックしたくない UI の更新に関連して行われます。

3 つの大きな例外があります。

  1. バックプレッシャーをサポートしていないデータ ソースを使用している (Web ソケット接続など)
  2. 受信(つまり、オブザーバー)に実際の非同期境界があります。これは、たとえば外部サービスと通信するときに発生する可能性があり、それがいつ完了するかわからない実際の未来です

可能ないくつかの解決策...

  1. サーバー通信がバックプレッシャをサポートしていない場合、最も簡単な方法は、バックプレッシャをサポートするようにサーバーを変更することです。また、通常の HTTP リクエストはバックプレッシャが自然に行われます (つまり、次のように簡単です)。Observable.interval(3.seconds).flatMap(_ => httpRequest("..."))
  2. それがオプションでない場合、Monifu にはバッファリング戦略があります...したがって、無制限のキューを使用できますが、バッファオーバーフローをトリガーして接続を閉じるキュー、またはバックプレッシャーを実行しようとするバッファリングも使用できます。バッファがいっぱいになると新しいイベントのドロップを開始し、古いイベントをドロップするための別のバッファリング戦略に取り組んでいます-キューの切断を回避する目的で
  3. 無制限にできるソースのソースで「マージ」を使用している場合は、それを行わないでください;-)
  4. 外部サービスへのリクエストを行っている場合は、それらを最適化してみてください。たとえば、イベントを Web サービスに送信して履歴を追跡したい場合は、データをグループ化し、リクエストをバッチ処理することができます。

ところで、ブラウザ側とタスクのスケジューリングの問題に関して、私が心配していることの 1 つは、Monifu が作業を効率的に中断しないことです。言い換えれば、おそらく長い同期ループを小さなループに分割する必要があります。なぜなら、一部のループが UI の更新をブロックしているため、パフォーマンスの問題に苦しむよりも悪いのは、UI に表示されるレイテンシの問題だからです。大きなタスクではなく、複数の小さなタスクをスケジューラに送信したいと考えています。ブラウザーでは、基本的に協調マルチタスクがあり、UI の更新を含め、すべてが同じスレッドで行われます。つまり、このスレッドを長時間ブロックする作業を行うのは非常に悪い考えです。

そうは言っても、私は現在、Javascript ランタイムを最適化し、より注意を払っているところです。setTimeoutよりも標準的であるため、使用されていますが、これらsetImmediateの側面についていくつかの作業を行います。

ただし、パフォーマンスが悪い具体的なサンプルがある場合は、ほとんどの問題を修正できるため、それらを伝えてください。

乾杯、

于 2015-03-03T17:27:17.230 に答える