[解決済み] 大なり小なりのSwitchステートメント
質問
ということで、このようなswitch文を使いたいのですが。
switch (scrollLeft) {
case (<1000):
//do stuff
break;
case (>1000 && <2000):
//do stuff
break;
}
これで、これらの文のどちらか(
<1000
) または (
>1000 && <2000
は動作しません(明らかに理由は違いますが)。 私が尋ねているのは、それを行うための最も効率的な方法です。 私は、30個の
if
ステートメントを使用したいので、switch構文を使用したいです。 何かいい方法はないでしょうか?
どのように解決するのですか?
他の回答で解決策を見たとき、パフォーマンスに悪いとわかっていることがいくつかありました。コメントに書こうと思ったのですが、ベンチマークして結果を共有した方が良いと思いました。あなたは 自分でテストする . 以下は、各ブラウザで最速の操作を行った後に正規化した私の結果です(ymmv)。
以下は、2021-MAY-05の結果です。
2021年のテストは、Windows 10 64bitで、以下のバージョンで実施しました。 Chrome 90.0.4430.212 , ファイアフォックス 89.0b13 , オペラ 76.0.4017.123 , エッジ 90.0.818.62 , ブレイブ 1.24.85 そして ノード 16.1.0 (WSLで実行されました)
Appleはアップデートしない Windows版Safari ということで、5.1.7のままです。今回のテストではBraveに変更しました。
こちらは過去比較のため、2012-09-04の結果です。
2012年のテストは、Windows 7 32bitで、以下のバージョンで実施しました。 クローム 21.0.1180.89m , Firefox 15.0 , オペラ 12.02 , MSIE 9.0.8112 , サファリ 5.1.7 . ノード は、Windows版Nodeのタイマーの解像度が1msではなく10msだったため、Linuxの64bitボックスで実行されました。
if-immediate(イフ・イミディエイト
この方法は、...を除くすべてのテストされた環境において最も速い方法です。 ドラムロール MSIE! (驚き、驚き)。
これが推奨される実装方法です。
if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
if-indirect
のバリエーションです。
switch-indirect-array
しかし
if
-ステートメントの代わりに、すべてのテストされたエンジンでより速いです。
2021年では最速のテストより20~120%(2012年:0~280%)遅くなっています。Chromeは2012年(1.2)よりも2021年(2.20)の方が時間がかかっている
values=[
1000, 2000, ... 30000
];
if (val < values[0]) { /* do something */ } else
if (val < values[1]) { /* do something */ } else
...
if (val < values[29]) { /* do something */ } else
スイッチ・イミディエイト
これは、計算をしてインデックスを得ることができる場合に有効です。
2021年には40~120%(2012年:0~180%)遅くなっています。
if-immediate
ただし、MSIEでは最速でした。
switch (Math.floor(val/1000)) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
スイッチ範囲
エンジンはそれぞれのケースで2回値を比較しなければならないので、遅くなります。
2021年のテストでは、最速の1~2.6倍(2012年:1.6~38倍)遅くなっています。 Chromeは38から3.6と最も大きな改善を遂げたが、依然としてテストされたエンジンの中で最も遅い。
switch (true) {
case (0 <= val && val < 1000): /* do something */ break;
case (1000 <= val && val < 2000): /* do something */ break;
...
case (29000 <= val && val < 30000): /* do something */ break;
}
スイッチ・レンジ2
のバリエーションです。
switch-range
が、1つのケースにつき1つの比較しかしないので、より高速になります。
エンジンは各ケースをソースコード順にテストするので、case 文の順序は重要です。
ECMAScript 2020 13.12.9
2021年のテストでは最速で36~107%遅かったが、2012年は1~31倍遅くなっている。このテストで最もパフォーマンスが悪いのは依然としてChromeですが、32倍から2倍に改善されています。
switch (true) {
case (val < 1000): /* do something */ break;
case (val < 2000): /* do something */ break;
...
case (val < 30000): /* do something */ break;
}
スイッチ・インダイレクト・アレイ
このバリエーションでは、範囲は配列に格納されます。
2021年のテストでは、最速で57~193%(2012年:3~35倍)遅くなっています。 テストしたすべてのエンジンでペルバランスが改善され、Chromeはまだ最も遅いものの、35から2.93に改善されました。
values=[1000, 2000 ... 29000, 30000];
switch(true) {
case (val < values[0]): /* do something */ break;
case (val < values[1]): /* do something */ break;
...
case (val < values[29]): /* do something */ break;
}
アレイリニアサーチ
このバリエーションでは、範囲は配列に格納されます。
2021年のテストでは、最速で57~193%(2012年:3~35倍)遅くなっています。 テストしたすべてのエンジンでペルバランスが改善され、Chromeはまだ最も遅いものの、35から2.93に改善されました。
values=[1000, 2000 ... 29000, 30000];
for (sidx=0, slen=values.length; sidx < slen; ++sidx) {
if (val < values[sidx]) break;
}
switch (sidx) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
アレイバイナスイッチ
の変形版です。
array-linear-switch
が、バイナリサーチで
残念ながら、線形探索より遅いです。私の実装のせいなのか、線形探索の方が最適化されているのかは分かりません。また、キースペースが小さすぎることも原因かもしれません。
2021年では4-5倍(2012年:4-16倍)遅くなっています。 を使用しないでください。 .
values=[0, 1000, 2000 ... 29000, 30000];
while(range) {
range = Math.floor( (smax - smin) / 2 );
sidx = smin + range;
if ( val < values[sidx] ) { smax = sidx; } else { smin = sidx; }
}
switch (sidx) {
case 0: /* do something */ break;
...
case 29: /* do something */ break;
}
まとめ
パフォーマンスを重視する場合は
if
-ステートメントまたは
switch
を、即値で表示する。
関連
-
[解決済み】WebpackとBabelで「このファイルタイプを扱うには適切なローダーが必要な場合があります。
-
[解決済み] jQueryでチェックボックスに "checked "を設定する
-
[解決済み] JavaScriptのオブジェクトが空であることをテストするにはどうすればよいですか?
-
[解決済み] jQueryの「exists」関数はありますか?
-
[解決済み] JavaScriptでNULL、未定義、空白の変数をチェックする標準的な関数はありますか?
-
[解決済み] Rubyのswitch文の書き方
-
[解決済み] Pythonのswitch文の代用品?
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
-
[解決済み] Stringでswitch文が使えないのはなぜですか?
-
[解決済み] JavaScriptで複数ケースを扱うSwitch文
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】document.getElementByIDは関数ではありません。
-
[解決済み】jquery $.ajaxオブジェクトのresponseJSONプロパティを取得する方法 [重複]。
-
[解決済み】NodeJS "ESモジュールをロードするためにインポートを使用する必要があります。"
-
[解決済み】最大呼び出しスタックサイズ超過エラーとその修正方法とは?
-
[解決済み】SyntaxError: 'import' と 'export' は 'sourceType: module' とだけ表示されるかもしれない - Gulp
-
[解決済み】JavaScript ランタイムエラー:'$'が未定義です。
-
[解決済み】SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
[解決済み】 Uncaught Reference Error: stLight is not defined (in Chrome only)
-
[解決済み】 \u003C とは何ですか?
-
[解決済み] [Solved] Uncaught Invariant Violation: 前のレンダリング中よりも多くのフックをレンダリングする