![](/img/trans.png)
[英]How to pass a large string from Python to a C++ extension method efficiently?
[英]Search a large c++ string from a file mapping quickly and efficiently
一個快速的序言,我在.Net非常舒服,但在c ++方面經驗有限,所以我不確定我是否做得很好。 我正在使用文件映射對象來檢索可能是一個相對較長的字符串,由多達數千個文件名組成。 可以從連接到Windows資源管理器的ImageOverlayHandler調用此函數,因此速度和內存消耗都很重要。 這個代碼可能會被一次數百個覆蓋請求調用(但僅限於邊緣情況)。 在下面的代碼中,這是一種有效的方法嗎? 使用這種方法,如果我已正確理解我的代碼,我將不會制作映射文件的本地副本,並且boost :: contains調用應該非常快。 關於我如何改進它,或者我應該如何做到這一點的任何想法? 在之前的迭代中我使用了矢量等,但似乎它會使用更多的內存。
HRESULT GetFolders()
{
HANDLE hMapFile;
LPCWSTR pBuf;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szFolderName); // name of mapping object
if (hMapFile == NULL)
{
return NULL;
}
pBuf = (LPCWSTR) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
CloseHandle(hMapFile);
return NULL;
}
wstring resOut = (wstring)pBuf;
bool val = boost::contains(resOut, L"C:\\FOLDER1");
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
}
由於您將此數據描述為文件名列表,因此請考慮將每個文件名放在std::set
或std::unordered_set
(C ++ 11)或boost::unordered_set
(C ++ 03及更高版本)中。
您的方法具有O(n)效率。
std::set
將具有O(log n)效率。
unordered_set
將具有O(1)效率。
注意:任何這些容器的創建都應該提前完成一次。 不是每次調用GetFolders()
如果您一次或僅偶爾創建文件名列表並重復測試,您可以從二進制搜索中受益。 二進制搜索需要兩件事:輸入列表必須排序,並且您必須能夠有效地索引到列表的任何元素。
在將文件寫入文件之前,可以通過在C#中對列表進行排序來滿足第一個要求。 您可以通過創建一個整數列表來滿足第二個要求,這些整數表示每個文件名開頭的字符串偏移量。 由於每個整數的大小都相同,因此可以將其編入索引,並且只需一個簡單的間接即可獲得實際的文件名。
std::equal_range
算法將進行二進制搜索。 如果返回的迭代器相等,則找不到該項,否則第一個迭代器指向它。
您需要一個自定義比較器函數來傳遞給equal_range
以對字符串執行間接操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.