3

特定のビットがバイトに設定されているかどうかを知りたい場合は、単純なANDマスクでうまくいきます。同じことを達成するためのより速い方法があるかどうか知りたいです。例として、ビットシフト<<または>>は、「落ちた」ビットではなく、シフトされた数値を返します。

マネージコードに代替手段がない場合、安全でないアセンブリを作成すると高速になりますか?もしそうなら、その方法を説明してください。

コンテキスト:これは、実稼働コード用に高度に最適化する必要がある複雑なアルゴリズム用です。恐ろしい「自分で宿題をする」コメントや反対票を避けるために、これを明確にする必要があると感じました。

4

2 に答える 2

6

シフト操作を介してビットテストを実行するには、ビットを2回シフト(符号なし)して、いずれかの側から余分なビットをノックオフする必要があります(特定の位置に戻す必要はありません。ゼロをテストするだけです)。 。これは複雑で最適ではありません。

不思議なことに、an&はビットテストを実行する標準的な方法であり、大幅に最適化されています。これは単一のCPU命令であり、非常に高速です。

&たとえば、テストを使用するだけif((x & MASK) != 0)です。

いいえ、unsafeここではコードは実際には役に立ちません。unsafe主にポインタに関心があります。ポインターは面白くて面白いですが、ポインターがなくてもまったく同じビットテストを実行できます。ここでのポインターの潜在的な使用法の1つは、ポインター強制を使用して、元の場合よりも多くのデータを一度にテストする方法があった場合です。たとえば、がありbyte[]、一度に8バイトをテストしたい場合は、を強制的にbyte[]byte*次に、byte*またはlong*を強制しulong*ます。これは、たとえば、Web-Socketマスキング(より広いxorマスクを使用してバイトストリームで動作する)で役立つ最適化になる可能性があります。ただし、これは単純なビットテストには必要ありません。

于 2012-08-06T21:42:47.727 に答える
3

前述のように、ビット演算は非常に効率的です。最新のプロセッサでは、事実上、このような操作はほぼ確実に1クロックサイクルで実行されます。

式用に生成された実際のコードを確認する場合は、VisualStudioデバッガーで起動します。ブレークポイントを設定し、ヒットしたら、メニューをクリックします:Debug..Windows..Disassembly。

たぶん、あなたの式が十分に複雑であれば、この種のことでコンパイラーとオプティマイザーを打ち負かすことができますが、私はそれを疑っています。さらに重要なことに、発生するパフォーマンスの問題は、ビットをいじることに関連している可能性はほとんどありません。問題が発生するまで最適化しないでください。ジェームズマイケルヘアが言うように:

最適化の2つの法則を覚えておいてください。これらを最初にどこで聞いたかはわかりませんが、本当です。

  • 初心者の場合:最適化しないでください。
  • 専門家の場合:まだ最適化しないでください。

信用できる。初心者の場合は、どんな犠牲を払っても最適化する衝動に抵抗してください。そして、あなたが専門家であるならば、その決定を遅らせてください。タスクに適切なデータ構造とアルゴリズムを選択している限り、パフォーマンスはおそらく十分すぎるでしょう。コードではなく、ネットワーク、データベース、またはディスクのヒットが速度低下になる可能性があります。彼らが言うように、あなたのコードのボトルネックの98%はあなたのコードの2%にあるので、時期尚早の最適化は測定可能な影響を与えない保守と安全の負債を追加するかもしれません。

代わりに、保守性と安全性をコード化してから、真のボトルネックを見つけたときにのみ、戻ってさらに最適化する必要があります。

詳細はこちら:

ビット操作に関連するほぼすべてのことを実行する方法については、ビットをいじるハックを参照してください。C言語を対象としていますが、同じ手法をC#でほとんど変更せずに機能します(たとえば、ポインターを含むものはすべて再考する必要があります)。

于 2012-08-06T23:07:28.217 に答える