こちらの記事は、Devin Soni 氏により2019年 11月に公開された『 Stop Using i++ in Your Loops 』の和訳です。
本記事は原著者から許可を得た上で記事を公開しています。
イントロダクション
これまでforループを書いたことがあるなら、ループ変数をインクリメントするために、ほぼ間違いなくi++
を使用したことがあるでしょう。
しかし、なぜそのように選ぶのかを考えたことがありますか?
明らかなこととして、i++
の結果、iは1大きくなります。それが我々が望むことです。しかし、これを実現するにあたって++i
やi++
、ひいてはi = i + 1
といった多くの方法があります。
この記事では、++i
とi++
という1を加算する2つの方法を取り扱い、ほとんどの状況で++i
がi++
よりも優れていると考えられる理由をご説明します。
後置インクリメント(i++)
i++
方式、または後置インクリメントは最も一般的な方法です。
擬似コードにおいて、後置インクリメント演算子は変数iに対して大まかに次のような振る舞いをします。
int j = i;
i = i + 1;
return j;
後置インクリメント演算子はインクリメント後の値i + 1
ではなく、元の値i
を返す必要があるため、古いバージョンのiを保持しておく必要があります。
これは、通常その値を保持するための追加メモリを不必要に使用するということを意味しており、なぜなら大抵の場合、古いバージョンのiを実際に使用することはなく、単に破棄されるためです。
前置インクリメント(++i)
++i
方式、または前置インクリメントはあまり一般的ではなく、通常、CやC ++などの言語を使用する古くからのプログラマーが使用します。
擬似コードにおいて、前置インクリメント演算子は変数iに対して大まかに次のような振る舞いをします
i = i + 1;
return i;
特にここでは古いiの値を保持する必要はありません。単に加算して返すだけです。
これはforループの典型的なユースケースと非常に適合しています。この状況では古い値が必要になることが、ほとんどないためです。
注意事項
後置インクリメントと前置インクリメントの違いを見て、後置インクリメントではキャッシュされたi
の値は使用されないため、コンパイラがその行を最適化により除去し、2つの演算子が同等になるということに気づいた方がいるかもしれません。
整数などのプリミティブ型には、これはおそらく当てはまります。
ただし、ユーザー定義型やオーバーロードされた+操作によるイテレータのような、より複雑な型の場合、コンパイラはキャッシュ操作を安全に最適化できない場合があります。
そのため、ほとんどの場合、インクリメントするものの前の値が必要でない限り、前置インクリメント演算子は後置インクリメント演算子よりも優れているか、同等であると考えられます。
翻訳協力
Original Author: Devin Soni
Thank you for letting us share your knowledge!
この記事は以下の方々のご協力により公開する事が出来ました。
改めて感謝致します。
選定担当: yumika tomita
翻訳担当: @satosansato3
監査担当: @nyorochan
公開担当: asuma yamada
ご意見・ご感想をお待ちしております
今回の記事は、いかがだったでしょうか?
・こうしたら良かった、もっとこうして欲しい、こうした方が良いのではないか
・こういったところが良かった
などなど、率直なご意見を募集しております。
いただいたお声は、今後の記事の質向上に役立たせていただきますので、お気軽にコメント欄にてご投稿ください。
みなさまのメッセージをお待ちしております。