javascript において ユーザに迷惑をかけない程度に 全速力で実行するということ(自己解決)

応答性能と実行性能のトレードオフについてめもっとく Javascript

基本的に失敗から学ぶ自爆日記です。

Javascript をやっていてレスポンスは早くしたいけど、処理もそこそこ高速にぶん回したいと思うようになって、実験してみます。

自作のプログラムが遅くて、遅くなった原因はJavascriptに原因があるわけではなく、
タイマループのまわし方がゆるすぎるという事が原因じゃないかなと思ってる。
ユーザにフラストレーションを与えたくない。でも全速力で実行するにはどうしたらいいのか。
それについてちょっと実験してみる。

アルゴリズムもあるけど今回はアルゴリズムは考えない。タイマに向き合いたい。

javascript では 他の言語みたいに全速力でloop回して他のタスクから共有リソースにアクセスできるようにゴニョるという手法は使えないように思う。自主的に息継ぎをする瞬間を考えてあげないとどうしても固まったみたいになってしまう。これってWindows3.1の時のプリエンプティブじゃないときにマルチタスクに何か似ているような気がする。基本的にjavascript というのは マルチタスク に向いていない言語だろうと思う。

えーっと、いきなりだけど、このページに対する解は、本を読んでいたらわかりました。
結論:Web Worker を使おう!
です。
〜〜〜〜以上〜〜〜


↑の本レビューすごく低いですが、わりといいと思ってます。

HTML5の本はハズレが90%位だと思います。何がダメって、マークアップを中心に語られている本はほとんど難しいことを避けて書かれている本が多いです。もちろん簡単な本にもニーズがあっていい本か悪い本かは人によって違うものですが、全然物足りなく感じる人の比率が高いような本が多い気がします。

この本は逆に内容は*そこそこ*ページ数の割につめ込まれていて、値段もそれほど高価すぎずいいかな。一つの機能に対するページ数は全然多くなくて、この本一冊で全部追求できるわけじゃないですが、APIのindex としてはいいと思います。HTML5 って何ができるんだろう?っていうことをjavascript プログラマの視点で俯瞰するための本だと思います。更に気になる部分はまた専門の情報は必要だと思います。

ただ、index として使うには
策定中のものも多いので、やっぱりその点低評価につながっちゃうというのも正しいかなあ。

私的にはこの本片手にGoogle検索でしばらく楽しめそうな感じはしてます。


〜〜〜〜〜
↓以下は実験する必要がなくなりましたので残骸です。

setTimeout() と setInterval() は録画予約に似る

内容に入る前に
まずは、javascript で timer を使う場合は二通りの方法があるという事を思い出す。
setTimeout() と setInterval()。
どちらも二つの引数を取り、1つ目は、関数。2つめはミリセコンドだ。
setTimeout()は何秒後かに実行してねというワンショットなものをタイマで呼び出す場合に使い。
setInterval()は間隔毎に実行してねというずっとやってほしい場合につかう。録画の特番1回限りの録画と毎週録画の違いみたいなもの。
ただ、setTimeout()でも、setTimeoutで呼ばれる関数の最後でさらにsetTimeoutする方法を書いておけばワンショット的ではないものにも使用可能だとおもう。
概要はこんな感じだけどちょっとこれはクセがあって、最初のうちは混乱する。

自分以外は誰も止められないのがJavascript

source1:

(function()

function nod(){
 console.log("ふむふむ");
}

console.log("あのですね");

setTimeout(nod,1000);//1秒後にうなずいてもらう約束をする。

//ビジーループで約2秒過ごす。
var startTime = new Date();
var endTime = new Date();
while (endTime - startTime < 2000 ){ endTime = new Date() };

console.log("というわけです");
)();

ビジーループのところは怒られそうなコードではあるけど実験なので許してください。

このコードは1秒後にうなづいてもらうようにTimeoutを設定している
でも、決して出力は

「あのですね」
「ふむふむ」
「というわけです」

にはならない。

「あのですね」
「というわけです」
のあとで
「ふむふむ」

になる。

setTimeoutはカウントダウンははじめていたとしても関数が呼び出されるのは、実行が終わったあとだ。javascript が関数を停止できるのって自らリターンした時であって、supervisor 的な誰かからによって割り込みによって動作を停止して別の作業をするようなことはできない設計になっていると思う。エラーが投げられたときは話は別だと思うが…。基本的にはそんなかんじ。ソースは知らない。

これは単純さをもたらしていてメリットも大きいと思う。

逆に例えばこれでもし「ふむふむ」が途中で実行されてしまう設計になっていると、実際問題大混乱することは間違いのではないかとおもう。

「ふむふむ」であれば実害はないけど、もし万が一、グローバル変数を上書きするような事があると、どのグローバル変数も信用でき無くなって安心してプログラミングができなくなってしまう。

この動作はsetIntervalでも変わりない。source1 の setTimeoutをsetIntervalに変えても
最後の「ふむふむ」が1秒毎に出力される以外は何も変わらない。

<つづきはまた今度かく 以下 TODO>

setInterval は複数実行されることはあるという事を読んだことがある。本当だろうか?

別のTimerIDであっても同じか


問題をシンプルにするために何がしのタスクを考えてみる。

今回は素数やフィボナッチはメモリ量とか有効桁数とか増えるし難しいので却下して、ひたすらインクリメントするという作業にする。

ただ、32ビットの数字だとあっという間に最大値に届いてしまうため、
絶望的にしょうもない関数を定義した。

function do_something(){
 if (counter == 1048576){
  mega_counter ++;
  counter = 0;
 }else {
  counter ++;
 }
}

これをユーザをいらいらさせずにどれだけ回せるかという事に注目してみたい。

0 件のコメント:

コメントを投稿