Đa luồng sẽ chỉ làm cho việc này diễn ra chậm hơn trừ khi bạn muốn quét nhiều tệp với mỗi tệp trên một ổ cứng khác. Nếu không, bạn sẽ chỉ tìm kiếm.
Tôi đã viết một chức năng thử nghiệm đơn giản bằng cách sử dụng các tệp ánh xạ bộ nhớ, với một chuỗi duy nhất một tệp 1,4 Gb mất khoảng 20 giây để quét. Với hai chủ đề, mỗi chủ đề lấy một nửa tập tin (thậm chí 1MB khối thành một chủ đề, lẻ với nhau), phải mất hơn 80 giây.
- 1 Chủ đề: 20.015 mili giây
- 2 chủ đề: 83.985 mili giây
Đúng vậy, 2 chủ đề là chậm hơn so với 1 chủ đề Bốn lần!
Đây là mã tôi đã sử dụng, đây là phiên bản luồng đơn, tôi đã sử dụng mẫu quét 1 byte, vì vậy mã để xác định vị trí phù hợp với ranh giới bản đồ không được kiểm tra.
HRESULT ScanForPattern(LPCTSTR pszFilename, LPBYTE pbPattern, UINT cbPattern, LONGLONG * pcFound)
{
HRESULT hr = S_OK;
*pcFound = 0;
if (! pbPattern || ! cbPattern)
return E_INVALIDARG;
// Open the file
//
HANDLE hf = CreateFile(pszFilename,
GENERIC_READ,
FILE_SHARE_READ, NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (INVALID_HANDLE_VALUE == hf)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
// catch an open file that exists but is in use
if (ERROR_SHARING_VIOLATION == GetLastError())
hr = HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
return hr;
}
// get the file length
//
ULARGE_INTEGER uli;
uli.LowPart = GetFileSize(hf, &uli.HighPart);
LONGLONG cbFileSize = uli.QuadPart;
if (0 == cbFileSize)
{
CloseHandle (hf);
return S_OK;
}
const LONGLONG cbStride = 1 * 1024 * 1024; // 1 MB stride.
LONGLONG cFound = 0;
LPBYTE pbGap = (LPBYTE) malloc(cbPattern * 2);
// Create a mapping of the file.
//
HANDLE hmap = CreateFileMapping(hf, NULL, PAGE_READONLY, 0, 0, NULL);
if (NULL != hmap)
{
for (LONGLONG ix = 0; ix < cbFileSize; ix += cbStride)
{
uli.QuadPart = ix;
UINT cbMap = (UINT) min(cbFileSize - ix, cbStride);
LPCBYTE pb = (LPCBYTE) MapViewOfFile(hmap, FILE_MAP_READ, uli.HighPart, uli.LowPart, cbMap);
if (! pb)
{
hr = HRESULT_FROM_WIN32(GetLastError());
break;
}
// handle pattern scanning over the gap.
if (cbPattern > 1 && ix > 0)
{
CopyMemory(pbGap + cbPattern - 1, &pb[0], cbPattern - 1);
for (UINT ii = 1; ii < cbPattern; ++ii)
{
if (pb[ii] == pbPattern[0] && 0 == memcmp(&pb[ii], pbPattern, cbPattern))
{
++cFound;
// advance by cbPattern-1 to avoid detecting overlapping patterns
}
}
}
for (UINT ii = 0; ii < cbMap - cbPattern + 1; ++ii)
{
if (pb[ii] == pbPattern[0] &&
((cbPattern == 1) || 0 == memcmp(&pb[ii], pbPattern, cbPattern)))
{
++cFound;
// advance by cbPattern-1 to avoid detecting overlapping patterns
}
}
if (cbPattern > 1 && cbMap >= cbPattern)
{
// save end of the view in our gap buffer so we can detect map-straddling patterns
CopyMemory(pbGap, &pb[cbMap - cbPattern + 1], cbPattern - 1);
}
UnmapViewOfFile(pb);
}
CloseHandle (hmap);
}
CloseHandle (hf);
*pcFound = cFound;
return hr;
}
(2) Mẫu có thể mở rộng ranh giới 100MB không? Nếu bạn phải tự viết thuật toán tìm kiếm và chuỗi tìm kiếm dài hợp lý (dài hơn thì tốt hơn!), Hãy xem xét thuật toán Boyer-Moore http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm – Kristen
@ Kristen: Mô hình sẽ không mở rộng biên giới 100MB, bởi vì mẫu có chút '1'. – Jichao
Mô hình là gì, nó thực sự là một bộ đơn? – GalacticJello