私は、同期パターン(0xDEADBEEF)とそれに続く固定サイズのデータブロックで整理された大きなバイナリファイル(2GB以上)を持っています。 例:matlabメモリマップの効率的なバイトパターン検索
0xDE AD BE EF ... 96 bytes of data
0xDE AD BE EF ... 96 bytes of data
... repeat ...
私は、各パケットの先頭にオフセットを特定する必要があります。理想的にはこれはちょうど[1:packetSize:fileSize]
になるでしょう。しかし、散在させることができる他のデータ、ヘッダなどがありますので、ファイルを検索して同期パターンを調べる必要があります。
私はLoren from Mathworks findPattern2に基づいていますが、メモリマップを使用するために少し変更した次のコードを使用しています。
function pattLoc = findPattern(fileName, bytePattern)
%Mem Map file
m = memmapfile(fileName);
% Find candidate locations match the first element in the pattern.
pattLoc = find(m.data==bytePattern(1));
%Remove start values that are too close to the end to possibly match
len = numel(bytePattern);
endVals = pattLoc+len-1;
pattLoc(endVals>length(m.data)) = [];
% loop over elements of Sync Pattern to check possible location validity.
for pattval = 2:len
% check viable locations in array
locs = bytePattern(pattval) == m.data(pattLoc+pattval-1);
pattLoc(~locs) = []; % delete false ones from indices
end
これはかなりうまく動作します。しかし、私は改善の余地があると思う。最初に私のパターンはpacketSize
(この例では100)よりも近くはできませんが、もっと離れているかもしれません。何とかこの情報を使って検索をスピードアップできるように思えます。次に、行5の最初の検索では、論理ではなく数字の索引付けにはfind
が使用されます。この行は論理的なままにしておくとほぼ2倍の時間がかかります。しかし、論理インデックスのみを使用してこの機能を再現しようとしましたが、悲惨に失敗しました。この問題は、ループ内で発生し、より多くの検索を使用せずに論理で入れ子になった索引付けを追跡したり、必要以上のデータをチェックしたりします。
これをスピードアップするのに役立つと思います。以下は、必要に応じて簡単なサンプルバイナリファイルを作成するコードです。 10000000個のパケットを使用してファイルを検索する
function genSampleFile(numPackets)
pattern = hex2dec({'DE','AD','BE','EF'});
fileName = 'testFile.bin';
fid = fopen(fileName,'w+');
for f = 1:numPackets
fwrite(fid,[pattern; uint8(rand(96,1)*255)],'uint8');
end
fclose(fid);
は次を取っ:
>> genSampleFile(10000000); %Warning Makes 950+MB file
>> tic;pattLoc = findPattern(fileName, pattern);toc
Elapsed time is 4.608321 seconds.
Mathworksの記事を見ると、Lorenは既に 'findPattern2'アルゴリズムと' strfind'を比較しました。大きなデータセットに対して 'strfind'は高速ではありません。あなたはlen == 100について正しいです。また、私は 'diff'をチェックすることで悪い場所を除外することができますが、この既知の最小距離情報を使って最初の検索を高速化するだけでなく、裏面。 –
memmapの場合、 'find(... == ...)'は*ファイル全体をメモリ上の '論理'配列に変換するので、 'strfind'は高速になります。 zLorenはすでにメモリ上にある配列で作業しています。その場合、findPattern2の例は本当に高速です。実際に 'memmap'の場合の' find'に対して 'strfind'バージョンを抑制しましたか? –