- ベストアンサー
バイナリからbit取得方法の改善と高速化について
- バイナリファイルの先頭から1bitずつ値を取得し、bitが立っているか判定する方法について、高速化や可読性の改善をご教授ください。
- 現在はファイルから1バイトずつ取得し、そのバイトとビット演算を行って最初のビットを判定していますが、よりスマートで高速な処理方法を模索しています。
- 修正案や参考になるサイトなど、どのような観点からでも構いませんので、アドバイスをいただければと思います。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
それでいいとおもいますよ。 細かなところでスピードアップできる書き方はあると思いますが、基本的はアルゴリズムは変わりません。 そもそもこの手の処理は、ディスクからのデータの読み込みそのものが一番遅いので、細かなところをがんばってスピードアップしても、全体としてはさほど速くならないことが多いです。 あと、特殊な状況で手抜きができる場合は、かなりのスピードアップができる可能性がありますが、それには#1さんがおっしゃるように、判定した情報をどのように利用するのかが重要な情報となります。
その他の回答 (5)
- yuipu
- ベストアンサー率38% (18/47)
メモリマップファイルを使うのがいいかもしれませんね。 使うAPIはこれくらいだったかな。 CreateFile CreateFileMapping MapViewOfFile UnmapViewOfFile CloseHandle
- salsberry
- ベストアンサー率69% (495/711)
> 判定した結果は、if文で判定し別の処理を行います C言語では0以外の値は真として扱うので、「(byte & mask) ? 0 : 1」のようにわざわざ三項演算子で0・1へ変換せずに「byte & mask」の結果をそのまま条件判定に使えばいいでしょう。ただし、真偽の判定を逆転する必要があります。プログラムの形によりますが、機械語にして一命令くらい減るかもしれません。 他の人が書いているようにファイルI/Oが占める時間が圧倒的なので、上記のようなことをやっても目に見えるような速度差は出ないと思います。
- magicalpass
- ベストアンサー率58% (378/648)
・一般論としてあまり巨大なファイルとかじゃなけりゃ、1バイト処理するごとに読み込むのじゃなく、一度に全部バッファに取り込んでから処理したほうが速いかと。 ・どういうデータを処理するのかわからないので場合によっては0x80が最上位ビットなのか、0x01が最上位ビットなのか、どちらから処理するのかというのを確認した方が良いかも。 ちなみにWindowsのデータを処理するときは最下位ビット(0x01)から処理する方が自然かと。
補足
ご回答ありがとうございます。 ・ファイルサイズは大きくなりうるので、バッファに持つかどうかは現在悩んでおります。 (メモリマップしても良いかなと・・・) ・エンディアンについては確認いたします。ご指摘ありがとうございますm(__)m
- tatsu99
- ベストアンサー率52% (391/751)
1案 (1)そのバイトと「(byte & 0x80) ? 0 : 1」を行い、最初のビットがたっているか判定する。 (2)次に、そのバイトを左へ1ビットシフトする。 (3)そのバイトと「(byte & 0x80) ? 0 : 1」を行い、最初のビットがたっているか判定する。 (4)次に、そのバイトを左へ1ビットシフトする。 ・・・・と8ビットぶん行います。 実際には(1)と(2)を8回繰り返せばOKです。(for文などで繰り返す) 2案 以下のようなテーブル(TBL)を用意する。 "00000000"・・・0x00(=0)に対応させる。 "00000001"・・・0x01(=1)に対応させる。 ・・・・ "11111111"・・・0xff(=255)に対応させる。 そのバイトをunsigned char data;とすると TBL[data]で、8個のビット列を一気に取得できます。 速さで比較すれば2案がお勧めですが、 速さをきにしないでよいなら、1案のほうが簡単でしょう。
補足
ご回答ありがとうございます。 1案) 判定を8ビット分用意するのではなく、シフトさせて同じ判定処理を行うという事ですね! 参考になりますm(__)m 2案) すいません、いまいち理解出来ないです。 8byteずつ処理する、という事でしょうか?
- salsberry
- ベストアンサー率69% (495/711)
各ビットが立っているかどうかの判定結果を使って何をするのでしょうか。その目的次第で最適な方法が変わるかもしれません。
補足
判定した結果は、if文で判定し別の処理を行いますが、 何をするかは関係なく、質問内容だけでの回答をお願いいたしますm(__)m
お礼
ご回答ありがとうございます。 読み込むバイナリが、かなり大きいサイズになる場合があり、 その場合、ほんの少しの高速化で、全体的にはそれなりに効果が出るのでは と思っております。 ファイルIOを減らしつつ、バイトシフトによる処理で考えてみたいと思います。