2017-08-29 37 views
-1

我有一个非常性能密集的应用程序,我真的想避免制作一个保存在unordered_map中的字符串的副本。我希望能够做的一个例子是将该字符串与本地字符串变量进行比较。是否可以访问unordered_map中的元素而不复制它的副本?

例如,

unordered_map<string,string> X; 
string test = "def"; 
X["abc"] = test; 

//other operations here... 

string* map_entry = X.???; //some operation that doesn't make a copy of the string 

size_t map_entry_size = (*map_entry).size(); 

for (size_t i = 0; i < map_entry_size; ++i) 
{ 
if ((*map_entry)[i] != test[i]) 
    throw 1; 
} 

这是可能的,或者必须我一直在使用它之前使元素的副本?

+10

不清楚为什么你认为你需要复制。 'operator []'返回一个引用,而不是一个副本... – user463035818

+5

取消引用迭代器返回一个引用,所以你没有复制那里。 – Jarod42

+3

无关:如果你曾经需要避免复制使用参考而不是指向安全的指针,你一些不必要的头痛 – user463035818

回答

3

[]运算符将返回一个引用或const引用,所以没有在那里复制。迭代器会给你一个std::pair<std::string, std::string>的引用,所以再次没有复制。

std::string &map_entry = X["abc"]; // Reference to value, no copy 
std::string *map_entry = &X["abc"]; // If you need a pointer 

如果你真的需要一个指针,做&map["key"]&iterator->second是有效的。

如果您在寻找性能,但是避免或至少小心使用std::string作为一个关键是一个更加显着的增益,尤其是如果键不是很短。

当然不认为仅仅因为一个无序的地图是O(1)一个std::unordered_map<std::string, T>几乎一样快,用说的整数键,并且其进一步从密集的整数键,可能仅仅是一个正常的阵列中去除(即使两者也将是O(1))。

  • 您需要临时创建一个std::string。最坏的情况是这是一个动态的内存分配。对于小字符串,您使用的标准库实现可能会有“小字符串优化”,但这仍然是一个副本。

    如果可能,您希望使用您已经从某个地方制作的现有std::string

  • 您需要计算散列(默认使用std::hash)和字符串长度为O(n)的字符串。

    std::string没有办法来缓存它的散列,所以重用(例如一个常量/静态)std::string不能避免这种情况,尽管你可以让你自己的字符串包装器。

  • 因为散列可能发生冲突,如果unordered_map没有找到一个条目,它则需要以防万一,再次O(n)是字符串的长度(所以实际上没有找到任何东西比快反正做一个完整的字符串比较找到正确的东西)。

使用说一个整数或其他小型固定大小的密钥(也考虑,如果你知道你的弦总是小于说,4首或8个字节,你可以让以“零填充”的整数),使散列是一个简单的数学运算,并且比较单个运算。

使用密集整数(比如一个枚举形式0到16)可以让你使用一个数组,并且数组索引非常快。

相关问题