簡體   English   中英

快速有效地從文件映射中搜索大型c ++字符串

[英]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::setstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM