パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

前置インクリメント(++x) よりも後置インクリメント(x++) のほうが高速?」記事へのコメント

  • b = a[i++] みたいな場合、
    まず a[i] の中身を取りに行く
    もう i は参照しちゃったので、i は変更可
    a[i] の中身を取りに行きながら、並行して i もインクリメント => 速い

    だけど、b = a[++] だと
    まず i をインクリメント
    インクリメントが終わらなきゃ、どこにアクセスしていいか分からない
    並行不可 => 遅い

    for( ほげ; ふが; i++) とか for( ほげ; ふが; ++i) の場合
    コンパイラが最適化しちゃうので、どっちも同じ

    結論: 習慣化する (≒考えずにやる) なら、後置で。

    • by vivisuke (31840) on 2015年04月20日 7時17分 (#2800356) 日記
      b = a[++i]; と b = a[i++]; では動作が違います。 動作が違うものの速度を単純に比べても意味が無いと思いますけどねー
      親コメント
      • by t-wata (10969) on 2015年04月20日 8時49分 (#2800375) 日記

        ループとかだと初期値を増減するだけで本質的に同じ動作にできますよ。

        親コメント
        • by Anonymous Coward

          それは本質的に同じ事をやることになるからです。

          「並列不可」が、ループしている部分の冒頭で起こるか、末尾で起こるかの差しか生じません

          b = a[i++]→iのインクリメントとa[i]を取ってくるのが並列可能
          b = a[++i]→a[i]を取ってくるのと、次回のiのインクリメントが並列可能

          ですから、差が出るとしても、ループの1回目冒頭と最終回の直後のみで微々たる差にしかならない上、
          その差も、多くはコンパイラが最適化して消し去ってくれるはずです。

          ですので、「早い方の書き方になるようにループの始め方を工夫してiを-1からスタートして...」といった努力は無駄に終わるでしょう。
          変則的な事はせず、スッキリ分かりやすい方のコードで書いた方が良いです。

          • by Anonymous Coward

            インデックスインクリメント付き配列アクセスに進入する直前にその処理を実行するか否かのストールが発生したりすると直撃しますよ。
            ゲームでボトルネックになるくらい回る場所では意外とありがちな処理なので、ぶち当たる人はぶち当たるTipsだと思う。
            CPUにもよるし、ホントいろいろな意味で状況次第だけど。

            • by Anonymous Coward

              そのパターンに思い至っておらず、別のツリーで似たような指摘を受けて試してみた [srad.jp]んですが、確かに影響しますね。

        • by Anonymous Coward

          周りを含めて同じ動作にできるのと、そのものの動作が違うってのは別だと思うんですけど

      • by Anonymous Coward

        本体部分の小さいループ最適化などではどちらのタイプを使用する変形を行うかによって1~2割変わることもあります
        ループ終了が回数指定などによって容易に推定可能であれば、ループをオーバーラップさせることでロードのレイテンシによるストールを回避できたりするんです。
        これは私がよく使う最適化の手です。

※ただしPHPを除く -- あるAdmin

処理中...