こんにちは, Shinoryoです.
今回は、if文とswitch文のどちらを積極的に使うべきかの見解をまとめてみました。
可読性
定数を列挙するような単純な条件分岐であれば、次のような理由からswitch文の方が分かりやすくなると思います。
- if文を使用した場合、条件を判定する変数を何回も書く必要がある。
- if文を使用した場合、ifの行、else ifの行、elseの行で条件式の位置が異なる。
- if文を使用した場合、その他の種類の条件分岐が入り込む可能性がある。
Javaでif文を使った例です。
private static int ifMatching(String value) { if (value == "a") { return 0; } else if (value == "b") { return 1; } else { return -1; } }
Javaでswitch文を使った例です。
private static int switchMatching(String value) { switch (value) { case "a": return 0; case "b": return 1; default: return -1; } }
if文を使うメリット
if文を使うメリットについても、考えられる範囲で補足します。
- 複雑な条件にも対応できる。
- うまく条件を記述すれば、
NullReferenceException
やNullPointerException
が発生しない。
パフォーマンス
言語によっては、switch文ではコンパイラーによる最適化が行われるため、switch文の方が高速です。
ifとswitchで迷ったらswitchを使いましょうという話(速度比較あり) #C# - Qiita
初めにプログラマの皆さんのほとんどはif文やswitch文のあるプログラミング言語を最低一つは使っていると思います。ifとswitchのどちらを使うか迷ったことはありませんか?この記事はそうい…
Java7のswitch文から得られるバイトコードの考察 - mikamikuhの何か
仕事ではJava6しか使ってないが(ごめんなさい)、Java7に 関する以下の文章を読んでいたらswitch文というものがよく分からなくなった。 Java SE 7 で導入された言語機能の 1 つは、switch 文の 判断基準の対象としてプリミティブ型や列挙型と同様に文字列型の変数を使えるようになったことです。(中略)一見、switch 文はネストさ れた if ... else 文に対する構文糖にすぎないように思えます。実際、開発者は、switch 文とネストされた if ... else 文のうち、どち らがコード内での見栄えが良いかを大方の基準として、いずれかを選ぶことが頻繁にあります。しかし…
速度比較(C#)
実際に、if文とswitch文の速度の差を検証してみました。
検証環境は次のとおり。
- OS:Microsoft Windows 11 Home
- CPU:Intel64 Family 6 Model 154 Stepping 3 GenuineIntel ~2100 Mhz
- メモリ:16 GB
検証に使用したコードは次のとおり。
using System.Diagnostics; namespace IfVsSwitch { public class Program { public static void Main(string[] args) { int num = 100; int num2 = 100000; Stopwatch swIf1 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { IfMatching1(i); } } swIf1.Stop(); Console.WriteLine(string.Format("if・3分岐:処理時間は{0} ms", swIf1.ElapsedMilliseconds)); Stopwatch swSwitch1 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { SwitchMatching1(i); } } swSwitch1.Stop(); Console.WriteLine(string.Format("switch・3分岐:処理時間は{0} ms", swSwitch1.ElapsedMilliseconds)); Stopwatch swIf2 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { IfMatching2(i); } } swIf2.Stop(); Console.WriteLine(string.Format("if・10分岐:処理時間は{0} ms", swIf2.ElapsedMilliseconds)); Stopwatch swSwitch2 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { SwitchMatching2(i); } } swSwitch2.Stop(); Console.WriteLine(string.Format("switch・10分岐:処理時間は{0} ms", swSwitch2.ElapsedMilliseconds)); Stopwatch swIf3 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { IfMatching3(i); } } swIf3.Stop(); Console.WriteLine(string.Format("if・100分岐:処理時間は{0} ms", swIf3.ElapsedMilliseconds)); Stopwatch swSwitch3 = Stopwatch.StartNew(); for (int j = 0; j < num2; j++) { for (int i = 0; i < num; i++) { SwitchMatching3(i); } } swSwitch3.Stop(); Console.WriteLine(string.Format("switch・100分岐:処理時間は{0} ms", swSwitch3.ElapsedMilliseconds)); } private static int IfMatching1(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else { return -1; } } private static int IfMatching2(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else if (value == 2) { return 2; } else if (value == 3) { return 3; } else if (value == 4) { return 4; } else if (value == 5) { return 5; } else if (value == 6) { return 6; } else if (value == 7) { return 7; } else if (value == 8) { return 8; } else { return -1; } } private static int IfMatching3(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else if (value == 2) { return 2; } else if (value == 3) { return 3; } else if (value == 4) { return 4; } else if (value == 5) { return 5; } else if (value == 6) { return 6; } else if (value == 7) { return 7; } else if (value == 8) { return 8; } else if (value == 9) { return 9; } else if (value == 10) { return 10; } else if (value == 11) { return 11; } else if (value == 12) { return 12; } else if (value == 13) { return 13; } else if (value == 14) { return 14; } else if (value == 15) { return 15; } else if (value == 16) { return 16; } else if (value == 17) { return 17; } else if (value == 18) { return 18; } else if (value == 19) { return 19; } else if (value == 20) { return 20; } else if (value == 21) { return 21; } else if (value == 22) { return 22; } else if (value == 23) { return 23; } else if (value == 24) { return 24; } else if (value == 25) { return 25; } else if (value == 26) { return 26; } else if (value == 27) { return 27; } else if (value == 28) { return 28; } else if (value == 29) { return 29; } else if (value == 30) { return 30; } else if (value == 31) { return 31; } else if (value == 32) { return 32; } else if (value == 33) { return 33; } else if (value == 34) { return 34; } else if (value == 35) { return 35; } else if (value == 36) { return 36; } else if (value == 37) { return 37; } else if (value == 38) { return 38; } else if (value == 39) { return 39; } else if (value == 40) { return 40; } else if (value == 41) { return 41; } else if (value == 42) { return 42; } else if (value == 43) { return 43; } else if (value == 44) { return 44; } else if (value == 45) { return 45; } else if (value == 46) { return 46; } else if (value == 47) { return 47; } else if (value == 48) { return 48; } else if (value == 49) { return 49; } else if (value == 50) { return 50; } else if (value == 51) { return 51; } else if (value == 52) { return 52; } else if (value == 53) { return 53; } else if (value == 54) { return 54; } else if (value == 55) { return 55; } else if (value == 56) { return 56; } else if (value == 57) { return 57; } else if (value == 58) { return 58; } else if (value == 59) { return 59; } else if (value == 60) { return 60; } else if (value == 61) { return 61; } else if (value == 62) { return 62; } else if (value == 63) { return 63; } else if (value == 64) { return 64; } else if (value == 65) { return 65; } else if (value == 66) { return 66; } else if (value == 67) { return 67; } else if (value == 68) { return 68; } else if (value == 69) { return 69; } else if (value == 70) { return 70; } else if (value == 71) { return 71; } else if (value == 72) { return 72; } else if (value == 73) { return 73; } else if (value == 74) { return 74; } else if (value == 75) { return 75; } else if (value == 76) { return 76; } else if (value == 77) { return 77; } else if (value == 78) { return 78; } else if (value == 79) { return 79; } else if (value == 80) { return 80; } else if (value == 81) { return 81; } else if (value == 82) { return 82; } else if (value == 83) { return 83; } else if (value == 84) { return 84; } else if (value == 85) { return 85; } else if (value == 86) { return 86; } else if (value == 87) { return 87; } else if (value == 88) { return 88; } else if (value == 89) { return 89; } else if (value == 90) { return 90; } else if (value == 91) { return 91; } else if (value == 92) { return 92; } else if (value == 93) { return 93; } else if (value == 94) { return 94; } else if (value == 95) { return 95; } else if (value == 96) { return 96; } else if (value == 97) { return 97; } else if (value == 98) { return 98; } else { return -1; } } private static int SwitchMatching1(int value) { switch (value) { case 0: return 0; case 1: return 1; default: return -1; } } private static int SwitchMatching2(int value) { switch (value) { case 0: return 0; case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 8; default: return -1; } } private static int SwitchMatching3(int value) { switch (value) { case 0: return 0; case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 8; case 9: return 9; case 10: return 10; case 11: return 11; case 12: return 12; case 13: return 13; case 14: return 14; case 15: return 15; case 16: return 16; case 17: return 17; case 18: return 18; case 19: return 19; case 20: return 20; case 21: return 21; case 22: return 22; case 23: return 23; case 24: return 24; case 25: return 25; case 26: return 26; case 27: return 27; case 28: return 28; case 29: return 29; case 30: return 30; case 31: return 31; case 32: return 32; case 33: return 33; case 34: return 34; case 35: return 35; case 36: return 36; case 37: return 37; case 38: return 38; case 39: return 39; case 40: return 40; case 41: return 41; case 42: return 42; case 43: return 43; case 44: return 44; case 45: return 45; case 46: return 46; case 47: return 47; case 48: return 48; case 49: return 49; case 50: return 50; case 51: return 51; case 52: return 52; case 53: return 53; case 54: return 54; case 55: return 55; case 56: return 56; case 57: return 57; case 58: return 58; case 59: return 59; case 60: return 60; case 61: return 61; case 62: return 62; case 63: return 63; case 64: return 64; case 65: return 65; case 66: return 66; case 67: return 67; case 68: return 68; case 69: return 69; case 70: return 70; case 71: return 71; case 72: return 72; case 73: return 73; case 74: return 74; case 75: return 75; case 76: return 76; case 77: return 77; case 78: return 78; case 79: return 79; case 80: return 80; case 81: return 81; case 82: return 82; case 83: return 83; case 84: return 84; case 85: return 85; case 86: return 86; case 87: return 87; case 88: return 88; case 89: return 89; case 90: return 90; case 91: return 91; case 92: return 92; case 93: return 93; case 94: return 94; case 95: return 95; case 96: return 96; case 97: return 97; case 98: return 98; default: return -1; } } } }
結果は次のとおり。switch文の方が高速であり、if文との差は分岐の数が多いほど顕著になりました。
条件 | 処理時間(ms) |
---|---|
if・3分岐 | 37 |
if・10分岐 | 27 |
if・100分岐 | 77 |
switch・3分岐 | 29 |
switch・10分岐 | 292 |
switch・100分岐 | 44 |
速度比較(Java)
実際に、if文とswitch文の速度の差を検証してみました。
検証環境は次のとおり。
- OS:Microsoft Windows 11 Home
- CPU:Intel64 Family 6 Model 154 Stepping 3 GenuineIntel ~2100 Mhz
- メモリ:16 GB
検証に使用したコードは次のとおり。
import java.util.stream.IntStream; public class App { public static void main(String[] args) { int num = 100; int num2 = 100000; long startTimeIf = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> ifMatching1(i)); } long endTimeIf = System.currentTimeMillis(); System.out.println(String.format("if・3分岐:処理時間は%d ms", endTimeIf - startTimeIf)); long startTimeSwitch = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> switchMatching1(i)); } long endTimeSwitch = System.currentTimeMillis(); System.out.println(String.format("switch・3分岐:処理時間は%d ms", endTimeSwitch - startTimeSwitch)); long startTimeIf2 = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> ifMatching2(i)); } long endTimeIf2 = System.currentTimeMillis(); System.out.println(String.format("if・10分岐:処理時間は%d ms", endTimeIf2 - startTimeIf2)); long startTimeSwitch2 = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> switchMatching2(i)); } long endTimeSwitch2 = System.currentTimeMillis(); System.out.println(String.format("switch・10分岐:処理時間は%d ms", endTimeSwitch2 - startTimeSwitch2)); long startTimeIf3 = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> ifMatching3(i)); } long endTimeIf3 = System.currentTimeMillis(); System.out.println(String.format("if・100分岐:処理時間は%d ms", endTimeIf3 - startTimeIf3)); long startTimeSwitch3 = System.currentTimeMillis(); for (int j = 0; j < num2; j++) { IntStream.rangeClosed(0, num).forEach(i -> switchMatching3(i)); } long endTimeSwitch3 = System.currentTimeMillis(); System.out.println(String.format("switch・100分岐:処理時間は%d ms", endTimeSwitch3 - startTimeSwitch3)); } private static int ifMatching1(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else { return -1; } } private static int ifMatching2(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else if (value == 2) { return 2; } else if (value == 3) { return 3; } else if (value == 4) { return 4; } else if (value == 5) { return 5; } else if (value == 6) { return 6; } else if (value == 7) { return 7; } else if (value == 8) { return 8; } else { return -1; } } private static int ifMatching3(int value) { if (value == 0) { return 0; } else if (value == 1) { return 1; } else if (value == 2) { return 2; } else if (value == 3) { return 3; } else if (value == 4) { return 4; } else if (value == 5) { return 5; } else if (value == 6) { return 6; } else if (value == 7) { return 7; } else if (value == 8) { return 8; } else if (value == 9) { return 9; } else if (value == 10) { return 10; } else if (value == 11) { return 11; } else if (value == 12) { return 12; } else if (value == 13) { return 13; } else if (value == 14) { return 14; } else if (value == 15) { return 15; } else if (value == 16) { return 16; } else if (value == 17) { return 17; } else if (value == 18) { return 18; } else if (value == 19) { return 19; } else if (value == 20) { return 20; } else if (value == 21) { return 21; } else if (value == 22) { return 22; } else if (value == 23) { return 23; } else if (value == 24) { return 24; } else if (value == 25) { return 25; } else if (value == 26) { return 26; } else if (value == 27) { return 27; } else if (value == 28) { return 28; } else if (value == 29) { return 29; } else if (value == 30) { return 30; } else if (value == 31) { return 31; } else if (value == 32) { return 32; } else if (value == 33) { return 33; } else if (value == 34) { return 34; } else if (value == 35) { return 35; } else if (value == 36) { return 36; } else if (value == 37) { return 37; } else if (value == 38) { return 38; } else if (value == 39) { return 39; } else if (value == 40) { return 40; } else if (value == 41) { return 41; } else if (value == 42) { return 42; } else if (value == 43) { return 43; } else if (value == 44) { return 44; } else if (value == 45) { return 45; } else if (value == 46) { return 46; } else if (value == 47) { return 47; } else if (value == 48) { return 48; } else if (value == 49) { return 49; } else if (value == 50) { return 50; } else if (value == 51) { return 51; } else if (value == 52) { return 52; } else if (value == 53) { return 53; } else if (value == 54) { return 54; } else if (value == 55) { return 55; } else if (value == 56) { return 56; } else if (value == 57) { return 57; } else if (value == 58) { return 58; } else if (value == 59) { return 59; } else if (value == 60) { return 60; } else if (value == 61) { return 61; } else if (value == 62) { return 62; } else if (value == 63) { return 63; } else if (value == 64) { return 64; } else if (value == 65) { return 65; } else if (value == 66) { return 66; } else if (value == 67) { return 67; } else if (value == 68) { return 68; } else if (value == 69) { return 69; } else if (value == 70) { return 70; } else if (value == 71) { return 71; } else if (value == 72) { return 72; } else if (value == 73) { return 73; } else if (value == 74) { return 74; } else if (value == 75) { return 75; } else if (value == 76) { return 76; } else if (value == 77) { return 77; } else if (value == 78) { return 78; } else if (value == 79) { return 79; } else if (value == 80) { return 80; } else if (value == 81) { return 81; } else if (value == 82) { return 82; } else if (value == 83) { return 83; } else if (value == 84) { return 84; } else if (value == 85) { return 85; } else if (value == 86) { return 86; } else if (value == 87) { return 87; } else if (value == 88) { return 88; } else if (value == 89) { return 89; } else if (value == 90) { return 90; } else if (value == 91) { return 91; } else if (value == 92) { return 92; } else if (value == 93) { return 93; } else if (value == 94) { return 94; } else if (value == 95) { return 95; } else if (value == 96) { return 96; } else if (value == 97) { return 97; } else if (value == 98) { return 98; } else { return -1; } } private static int switchMatching1(int value) { switch (value) { case 0: return 0; case 1: return 1; default: return -1; } } private static int switchMatching2(int value) { switch (value) { case 0: return 0; case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 8; default: return -1; } } private static int switchMatching3(int value) { switch (value) { case 0: return 0; case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; case 5: return 5; case 6: return 6; case 7: return 7; case 8: return 8; case 9: return 9; case 10: return 10; case 11: return 11; case 12: return 12; case 13: return 13; case 14: return 14; case 15: return 15; case 16: return 16; case 17: return 17; case 18: return 18; case 19: return 19; case 20: return 20; case 21: return 21; case 22: return 22; case 23: return 23; case 24: return 24; case 25: return 25; case 26: return 26; case 27: return 27; case 28: return 28; case 29: return 29; case 30: return 30; case 31: return 31; case 32: return 32; case 33: return 33; case 34: return 34; case 35: return 35; case 36: return 36; case 37: return 37; case 38: return 38; case 39: return 39; case 40: return 40; case 41: return 41; case 42: return 42; case 43: return 43; case 44: return 44; case 45: return 45; case 46: return 46; case 47: return 47; case 48: return 48; case 49: return 49; case 50: return 50; case 51: return 51; case 52: return 52; case 53: return 53; case 54: return 54; case 55: return 55; case 56: return 56; case 57: return 57; case 58: return 58; case 59: return 59; case 60: return 60; case 61: return 61; case 62: return 62; case 63: return 63; case 64: return 64; case 65: return 65; case 66: return 66; case 67: return 67; case 68: return 68; case 69: return 69; case 70: return 70; case 71: return 71; case 72: return 72; case 73: return 73; case 74: return 74; case 75: return 75; case 76: return 76; case 77: return 77; case 78: return 78; case 79: return 79; case 80: return 80; case 81: return 81; case 82: return 82; case 83: return 83; case 84: return 84; case 85: return 85; case 86: return 86; case 87: return 87; case 88: return 88; case 89: return 89; case 90: return 90; case 91: return 91; case 92: return 92; case 93: return 93; case 94: return 94; case 95: return 95; case 96: return 96; case 97: return 97; case 98: return 98; default: return -1; } } }
結果は次のとおり。switch文の方が高速であり、if文との差は分岐の数が多いほど顕著になりました。
条件 | 処理時間(ms) |
---|---|
if・3分岐 | 21 |
if・10分岐 | 13 |
if・100分岐 | 113 |
switch・3分岐 | 9 |
switch・10分岐 | 24 |
switch・100分岐 | 44 |
結論
switch文でも簡単に書けるような条件分岐である前提ですが、可読性・パフォーマンスの両面から、switch文を積極的に用いた方が良いと思います。
参考文献
- le-nn様による「ifとswitchで迷ったらswitchを使いましょうという話(速度比較あり)」
ifとswitchで迷ったらswitchを使いましょうという話(速度比較あり) #C# - Qiita
初めにプログラマの皆さんのほとんどはif文やswitch文のあるプログラミング言語を最低一つは使っていると思います。ifとswitchのどちらを使うか迷ったことはありませんか?この記事はそうい…
- yu-tarrrr様による「ifとswitchどっちがいいのか問題」
ifとswitchどっちがいいのか問題 #Java - Qiita
はじめにみなさんコーディングをしてきて、今までに何回ifを書いてきましたか?笑何万回と書い ていても、たまにswitchを使うかifを使うか悩みますよね??(僕は悩むことがあります)今の僕の選択…
- 「Java7のswitch文から得られるバイトコードの考察」
Java7のswitch文から得られるバイトコードの考察 - mikamikuhの何か
仕事ではJava6しか使ってないが(ごめんなさい)、Java7に 関する以下の文章を読んでいたらswitch文というものがよく分からなくなった。 Java SE 7 で導入された言語機能の 1 つは、switch 文の 判断基準の対象としてプリミティブ型や列挙型と同様に文字列型の変数を使えるようになったことです。(中略)一見、switch 文はネストさ れた if ... else 文に対する構文糖にすぎないように思えます。実際、開発者は、switch 文とネストされた if ... else 文のうち、どち らがコード内での見栄えが良いかを大方の基準として、いずれかを選ぶことが頻繁にあります。しかし…
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)