繁体   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