2018/06/24 公開
・2倍と左ビットシフトの速度
ここでは、int型の変数の掛け算による2倍('*2')、左ビットシフト1回('<<1')による2倍の2種類の計算を、それぞれ1000万回行い、処理開始から終了するまでの時間をナノ秒単位で計測しました。2つ違う計算方法で計算した結果は同じです。
また、この処理を9回繰り返し行いました。
ここから、計測につかったJavaのソースコードの解説と、結果を解説していきます。
TimeBitshiftL1.java ← クリックしてダウンロードページに移動
001: public class TimeBitshiftL1 { 002: public static void main( String[] args ) { 003: int number; 004: int x; 005: long ts, te, tresult1, tresult2; 006: 007: // 9回計測 008: for ( number = 1; number <= 9; ++ number ) { 009: // 2倍 010: ts = System.nanoTime(); 011: x = 0; 012: for ( int i = 1; i <= 10000000; ++ i ) { 013: x = x * 2; 014: } 015: te = System.nanoTime(); 016: tresult1 = te - ts; 017: 018: // ビットの左シフト 019: ts = System.nanoTime(); 020: x = 0; 021: for ( int i = 1; i <= 10000000; ++ i ) { 022: x = x << 1; 023: } 024: te = System.nanoTime(); 025: tresult2 = te - ts; 026: 027: // 結果表示 028: System.out.println( number + "回目 2倍:" + tresult1 029: + "ナノ秒 左シフト:" + tresult2 030: + "ナノ秒 " 031: + (double)tresult2 / (double)tresult1 ); 032: } 033: } 034: }
TimeBitshiftL1.Javaの出力結果
1回目 2倍:4520189ナノ秒 左シフト:3852210ナノ秒 0.8522232145602762 2回目 2倍:3995899ナノ秒 左シフト:3803886ナノ秒 0.9519474841581331 3回目 2倍:3817571ナノ秒 左シフト:3803886ナノ秒 0.9964152598602619 4回目 2倍:3856914ナノ秒 左シフト:3831255ナノ秒 0.993347271938135 5回目 2倍:3813294ナノ秒 左シフト:3782931ナノ秒 0.9920375926954491 6回目 2倍:4112645ナノ秒 左シフト:4225970ナノ秒 1.0275552594498187 7回目 2倍:4683549ナノ秒 左シフト:4179357ナノ秒 0.8923483025372426 8回目 2倍:4179784ナノ秒 左シフト:3947575ナノ秒 0.9444447368572156 9回目 2倍:3959548ナノ秒 左シフト:3805597ナノ秒 0.9611190469215173
結果の1番右の数値は、左シフトの処理時間を2倍の処理時間で割ったものです。
この値が0.0未満の場合、2倍の処理時間が左シフトの処理時間より長かったことを意味してします。1.0より大きい場合、2倍の処理時間が左シフトの処理時間より短かったことを意味してします。
この結果から、2倍の処理時間が左シフトの処理時間より少しだけ長くなりそうなことがわかります。6回目の結果は、左シフトの処理時間のほうが長かったことを示しているので、左シフトの処理時間が必ずしも短いとはいえません。
ここから、ソースコードの主要部分について解説してきます。
009: // 2倍 010: ts = System.nanoTime(); 011: x = 0; 012: for ( int i = 1; i <= 10000000; ++ i ) { 013: x = x * 2; 014: } 015: te = System.nanoTime(); 016: tresult1 = te - ts;
int型の変数xに0を代入して、その変数xに対して2倍する処理を1000万回行っています。処理終了時間tsと処理開始時間tsの差を処理時間tsresult1に代入しています。
018: // ビットの左シフト 019: ts = System.nanoTime(); 020: x = 0; 021: for ( int i = 1; i <= 10000000; ++ i ) { 022: x = x << 1; 023: } 024: te = System.nanoTime(); 025: tresult2 = te - ts;
int型の変数xに0を代入して、その変数xに対して1回の左ビットシフトを1000万回行っています。処理終了時間tsと処理開始時間tsの差を処理時間tsresult2に代入しています。
次に、"TimeBitshiftL1.Java"の2倍する値と左シフトする回数をint型の変数に変更したソースコードで処理時間の比較を行いました。
TimeBitshiftL2.java ← クリックしてダウンロードページに移動001: public class TimeBitshiftL2 { 002: public static void main( String[] args ) { 003: int number; 004: int x; 005: int mulnum, shiftnum; 006: long ts, te, tresult1, tresult2; 007: 008: // 掛ける値 009: mulnum = 2; 010: 011: // 左シフトの回数 012: shiftnum = 1; 013: 014: // 9回計測 015: for ( number = 1; number <= 9; ++ number ) { 016: // 2倍 017: ts = System.nanoTime(); 018: x = 0; 019: for ( int i = 1; i <= 10000000; ++ i ) { 020: x = x * mulnum; 021: } 022: te = System.nanoTime(); 023: tresult1 = te - ts; 024: 025: // ビットの左シフト 026: ts = System.nanoTime(); 027: x = 0; 028: for ( int i = 1; i <= 10000000; ++ i ) { 029: x = x << shiftnum; 030: } 031: te = System.nanoTime(); 032: tresult2 = te - ts; 033: 034: // 結果表示 035: System.out.println( number + "回目 2倍:" + tresult1 036: + "ナノ秒 左シフト:" + tresult2 037: + "ナノ秒 " 038: + (double)tresult2 / (double)tresult1 ); 039: } 040: } 041: }
TimeBitshiftL2.Javaの出力結果
1回目 2倍:12144639ナノ秒 左シフト:8008474ナノ秒 0.6594246234902494 2回目 2倍:11487779ナノ秒 左シフト:7952025ナノ秒 0.6922160497690633 3回目 2倍:11540380ナノ秒 左シフト:7894293ナノ秒 0.6840583239026791 4回目 2倍:11443304ナノ秒 左シフト:7936203ナノ秒 0.6935237410454184 5回目 2倍:11503174ナノ秒 左シフト:7922518ナノ秒 0.6887245207279312 6回目 2倍:11448008ナノ秒 左シフト:7917814ナノ秒 0.6916324656656424 7回目 2倍:11448008ナノ秒 左シフト:7995217ナノ秒 0.6983937292846056 8回目 2倍:11449292ナノ秒 左シフト:7932781ナノ秒 0.6928621437902012 9回目 2倍:11414224ナノ秒 左シフト:7926367ナノ秒 0.6944288985392262
9回の全ての計測結果が、左シフトの処理時間のほうが短いことを示しています。
この結果から、2倍の処理時間が左シフトの処理時間より3割程度長くなるがわかります。
最後に、"TimeBitshiftL1.Java"と"TimeBitshiftL2.Java"の処理時間を比較します。
TimeBitshiftL1.Javaの出力結果(1回目だけ)
1回目 2倍:4520189ナノ秒 左シフト:3852210ナノ秒 0.8522232145602762
TimeBitshiftL2.Javaの出力結果(1回目だけ)
1回目 2倍:12144639ナノ秒 左シフト:8008474ナノ秒 0.6594246234902494
この結果の2倍の処理時間の比率は、
4520189 : 12144639 = 1 : 2.6867…
です。
この結果の左シフトの処理時間の比率は、
3852210 : 8008474 = 1 : 2.0789…
です。
倍数とシフト数を変数に変更することで2倍以上の処理時間がかかることが確認できました。
ここから、ソースコードの主要部分について解説してきます。
008: // 掛ける値 009: mulnum = 2;
011: // 左シフトの回数 012: shiftnum = 1;
int型の変数shiftnumに左シフト回数1を代入しています。
016: // 2倍 017: ts = System.nanoTime(); 018: x = 0; 019: for ( int i = 1; i <= 10000000; ++ i ) { 020: x = x * mulnum; 021: } 022: te = System.nanoTime(); 023: tresult1 = te - ts;
int型の変数xに0を代入して、その変数xに対してmulnum倍する処理を1000万回行っています。処理終了時間tsと処理開始時間tsの差を処理時間tsresult1に代入しています。
025: // ビットの左シフト 026: ts = System.nanoTime(); 027: x = 0; 028: for ( int i = 1; i <= 10000000; ++ i ) { 029: x = x << shiftnum; 030: } 031: te = System.nanoTime(); 032: tresult2 = te - ts;
int型の変数xに0を代入して、その変数xに対してshiftnum回の左ビットシフトを1000万回行っています。処理終了時間tsと処理開始時間tsの差を処理時間tsresult2に代入しています。
以上です。
■関連コンテンツ
ビットシフト | ビットのずらしかた |
時間計測 | 時間を計測する方法を解説 |
ビット演算子 | ビット演算子について解説 |
Javaの変数 | Javaで扱う変数について解説 |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |