2013-05-04 90 views
4

例如:std :: map是否支持缓存?

CODE1:

if((iter = map.find(key)) != map.end()) { 
    return iter->second; 
} 
return 0; 

码2:

if(map.count(key) > 0) { 
    return map.at(key); 
} 
return 0; 

CODE2得多简单,但两者map.count()map.at()成本O(logn)时间的时间。 std::map是否提供了一项功能,可以将最后一个搜索项存储在缓存中,并且可以更快地搜索相同的项目,还是只是在整个地图中执行第二次搜索?

回答

5

它通过整个地图进行搜索,没有缓存正在完成 - 或者至少,标准没有强制执行,我会说没有执行它,因为所有这样的实现的客户端将有以支付在每次插入/移除后更新缓存信息的可能不希望的开销。

第一种方法是确定键/值对是否包含在一个地图(只介意operator ->应该使用的operator .,因为你从find()得到的是一个迭代的事实,习惯的方法,和分配iter应该是if条件外):

auto iter = map.find(key); 
if (iter != map.end()) { 
    return iter->second; 
} 
+0

+1尽管将第一个示例中的条件分成两行将会更清楚地表明IMO。 – dyp 2013-05-04 10:56:08

+0

@DyP:同意,我试图在我更新的答案中反映出这个问题 – 2013-05-04 11:00:11

+0

@AndyProwl:建议的检索函数与std :: map :: at(自C++ 11以来)做同样的事情 – dalle 2013-05-04 11:07:48

4

没有,没有C++标准库实现使用缓存,据我所知。 C++ 11要求容器对于多个读取器是线程安全的。并且为了完成对缓存的访问需要同步。即使你不想要,这会导致速度惩罚。 C++的一个标准做法是,你不应该支付任何你不明确需要或想要的东西。

+0

std :: map是否保证为标准的多个阅读器(假设没有编写者)是线程安全的?否则,这种说法没有道理。 – Zarat 2013-05-04 11:01:27

+2

@Zarat:是的,根据C++ 11它是。 – dalle 2013-05-04 11:06:21

+0

所以得出的结论是,由于该标准要求线程安全,因此缓存需要也是线程安全的,这会减慢不想/不需要它的呼叫者。 – Zarat 2013-05-04 11:12:01

1

它可以,但我知道没有。惯用的解决方案是 从而使用一个变量:

auto results = myMap.find(key); 
return results == myMap.end() 
    ? NULL 
    : &results->second; 

短,清洁和容易理解的。 (并且它避免了使得程序正确性推理如此困难的多重回报)。