🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
並列処理

複数の計算が同時に実行される手法

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

4回答

1724閲覧

実行したい処理が間に合わず遅延してしまう場合の回避方法について

X001017

総合スコア6

並列処理

複数の計算が同時に実行される手法

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2021/03/11 01:22

編集2021/03/11 07:11

マウスを移動する毎にそのマウスポジションを取得し、その値を関数にて計算し配列へとpushすると毎回30程度のデータができます。
その配列の値を頭から順に処理しようとfor文を使い(今回はlogのみの出力です)処理を施しますが、最初の内は問題なくconsole.logへ数値が出力されます。
しかし、マウスのポジションは常に動いているためか動作が間に合わずlogの出力が遅延してしまいます。
動作自体はしており、しばらく待つとlogが出力されますが遅延が酷くとても使用に耐えられません。このような場合、遅延など無く上手く処理するするにはどの様にするのが良いでしょうか。宜しくお願い致します。

JavaScript

1let point = []; 2 3let width = window.innerWidth; 4let height = window.innerHeight; 5let x0 = null; 6let y0 = null; 7 8 window.addEventListener('mousemove', (event) => { 9 point[]; 10 x0 = Math.floor(((event.clientX / width) * 100)); 11 y0 = Math.floor(((event.clientY / height) * 100)); 12 //計算の呼び出し 13 test(x0, y0) 14 for(key in point){ 15 console.log(point[key].x); 16 console.log(point[key].y); 17 } 18 }, false); 19 20function test(x0, y0) { 21 const px = Math.abs(x1 - x0); 22 . 23 . 24 //別途計算式があります 25 . 26 . 27 28 point.push({x:x0, y:y0});} 29 30 return point; 31 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/03/11 01:28

ご提示のコードで、イベントコールバックの後に書いている「point[];」だけの行は、何をしているつもりなのでしょうか?
X001017

2021/03/11 01:30

すいません、消し忘れで配列を初期化していたものが入っているだけです。
guest

回答4

0

コメントに書かれたコードだとmousemoveイベントハンドラが複数登録される問題がありますが、それを直してもだんだん遅くなりますね。
どうやらコンソールにログが溜まっていくとconsole.log()の実行が遅くなっていくようです。「console.log()が何回か呼ばれたらconsole.clear()を呼ぶ」などとして回避できるようです。また、console.log()を使わずにメインのページにログ出力するとそんなに遅くなりませんでした。例:

html

1<script> 2... 3 x1 = event.clientX / width; 4 y1 = event.clientY / height; 5 let ul = document.querySelector('#log'); 6 let li = document.createElement('li'); 7 ul.appendChild(li).textContent = `${x0}, ${y0}, ${x1}, ${y1}`; 8 li.scrollIntoView(); 9 x0 = x1; 10 y0 = y1; 11 break; 12... 13</script> 14<<ul id="log" style="height:6em;; overflow-y:scroll; position:absolute; width:90%; bottom:0px;"></ul>

以下、古い回答です。

過去のpointの内容は要らないということなので、イベントハンドラの先頭で空にしてしまえば良いのではないでしょうか。

js

1window.addEventListener('mousemove', (event) => { 2 point = []; 3 ...

(そもそもグローバル変数である必要もないのかもしれません)

配列を順に走査するにのふつうは for in は使わないと思います。通常の for か for of でしょう。速度には関係しないと思いますが。

js

1for (let i = 0; i < point.length; ++i) { 2 console.log(point[i].x); 3 console.log(point[i].y); 4}

js

1for (let p of point) { 2 console.log(p.x); 3 console.log(p.y); 4}

投稿2021/03/11 02:30

編集2021/03/11 13:19
int32_t

総合スコア21679

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

X001017

2021/03/11 04:32

すいませんありがとうございます。イベントの開始にforで処理するconsole.logが間に合っていないのか、イベントの開始と初期化のタイミングがやはりマズイのでしょうか。実際のものはどうもイベントハンドラ直後に初期化なされているようではありました。for inに関してはありがとうございます。
int32_t

2021/03/11 04:44

であれば、問題が再現できるソースを開示していただかないと助言は無理です。
X001017

2021/03/11 06:55

初期化のタイミングがイベントハンドラ直後であること以外はほぼそのままのソースではあります。mousemoveなのでイベントが発生するまでの期間が短すぎるというようなことはあったりしますでしょうか。このような場合は非同期処理などをして変わるものでしょうか。
int32_t

2021/03/11 07:04

経験的には、毎mousemoveでたかが30個程度の配列を生成するぐらいで遅くなったりしない感触です。なので、再現するコードがないと何とも言えません。
X001017

2021/03/11 12:48

ありがとうございます。 現状、Chromeのデベロッパーツール上でテストとして試している程度なのですが、そのような環境上でこのようなことが起きることはあり得ますでしょうか。Chromeで起きうることなのか知りたいところではありました。 また、下記の通りの配列などを使わず、ただ単にconsole.logの結果のみを出し続けるものでも同様に問題が起きるのですが、これは正しい反応でしょうか。よろしくお願いいたします。 let width = window.innerWidth; let height = window.innerHeight; let count = 1; let x0 = null; let y0 = null; let x1 = null; let y1 = null; window.addEventListener('mousedown', (event) => { window.addEventListener('mousemove', (event) => { switch(count) { case 1: x0 = event.clientX / width; y0 = event.clientY / height; count = 2; console.log('case 1:'); break; default: console.log('case 2:'); x1 = event.clientX / width; y1 = event.clientY / height; console.log(x0, y0, x1, y1); x0 = x1; y0 = y1; break; } }, false); }, false); window.addEventListener('mouseup', (event) =>{ count = 1; }, false);
int32_t

2021/03/11 13:10

現象を確認しました。回答を更新します。
X001017

2021/03/11 13:30

ありがとうございます。cnsole.logも溜まると実行上問題が出るのですね。実際の使用ではconsole.logの部分を本来使用するコードへ置き換えるつもりで、テスト上このような形でも問題が起きていたため非常に悩んでおりました。一度実際のものへ置き換えてみたいとは思います。配列上において30固定度の配列の生成、使用において経験上問題がないとのことで、テストできましたらと思います。いろいろ有難うございます。
guest

0

すいません、消し忘れで配列を初期化していたものが入っているだけです。

途中での配列の初期化をどこでも行っていない以上、マウスの動きでデータが積もっていけば過去の分まですべてを毎回出力し続けることとなりますが、それは意図した動作でしょうか?

投稿2021/03/11 01:33

編集2021/03/11 01:34
maisumakun

総合スコア145967

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

X001017

2021/03/11 01:38

過去の分については処理したくないので、ここでの配列の初期化はこれでよいのかもしれません。
maisumakun

2021/03/11 01:41

> ここでの配列の初期化はこれでよいのかもしれません。 位置としてもコード内容の面でも正しくありません(そのままのコードではそもそも実行できません)。
X001017

2021/03/11 02:10

全てのコードは記載していないのですが、実行はできているので、for文ではなく他のものを使用した方が良い等はありますでしょうか。
maisumakun

2021/03/11 04:53

> 全てのコードは記載していないのですが 問題を再現するのに必要十分なソースを示してください。初期化をやっているのかやっていないのかすら、これまでのやり取りから読み取ることができません。
maisumakun

2021/03/11 07:19

point[];は何も行いません。初期化したいならpoint=[];ではないでしょうか。
guest

0

処理自体が重いなら遅延なく対応することはできないでしょう
あえて言えば高速なマシンを使うことです
現実的なのは取得するデータを間引くことです

投稿2021/03/11 01:29

yambejp

総合スコア116661

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2021/03/11 04:18

一旦最小限動作するものを提示ください その上で調整できるかテストしてみます
guest

0

過去の分については処理したくないので、

ということなので、現在の計算結果だけ出力すれば良いと考えます。

JavaScript

1const width = 10, height = 10; // 不明な変数 width, height があるので、とりあえず初期化しておく 2 3window.addEventListener('mousemove', event => { 4 const x = Math.floor(((event.clientX / width) * 100)); 5 const y = Math.floor(((event.clientY / height) * 100)); 6 const point = test(x, y); 7 8 console.log('x', point.x); 9 console.log('y', point.y); 10}, false); 11 12function test(x, y) { 13 //別途計算式があります 14 return {x: x, y: y}; 15}

Re: X001017 さん

投稿2021/03/11 04:55

think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

X001017

2021/03/11 06:58

ありがとうございます。現在の計算結果は配列になるためどうしても頭から取り出して処理したい次第です。
think49

2021/03/11 09:54 編集

「現在の計算結果は配列」とはどういう意味でしょうか。 配列pointに格納された全要素が「現在の計算結果」なのですか。 だとすると、マウスカーソルを動かす度に要素数が増えていきますので、出力数も増えていき、遅延時間が増えていくのは仕方がない事であるといえます。 計算に必要なデータの内訳、計算結果の内訳を詳しく書いて下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問