这个问题的答案还取决于创建您在地图中存储的值类型的成本:
typedef std::map <int, int> MapOfInts;
typedef std::pair <MapOfInts::iterator, bool> IResult;
void foo (MapOfInts & m, int k, int v) {
IResult ir = m.insert (std::make_pair (k, v));
if (ir.second) {
// insertion took place (ie. new entry)
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.first->second = v;
}
}
对于诸如 int 之类的值类型,上面的方法比 find 后跟 insert 更有效(在没有编译器优化的情况下)。如上所述,这是因为在地图中的搜索只发生了一次。
但是,插入调用要求您已经构造了新的“值”:
class LargeDataType { /* ... */ };
typedef std::map <int, LargeDataType> MapOfLargeDataType;
typedef std::pair <MapOfLargeDataType::iterator, bool> IResult;
void foo (MapOfLargeDataType & m, int k) {
// This call is more expensive than a find through the map:
LargeDataType const & v = VeryExpensiveCall ( /* ... */ );
IResult ir = m.insert (std::make_pair (k, v));
if (ir.second) {
// insertion took place (ie. new entry)
}
else if ( replaceEntry ( ir.first->first ) ) {
ir.first->second = v;
}
}
为了调用“插入”,我们支付了构建值类型的昂贵调用 - 根据您在问题中所说的,您 20% 的时间不会使用这个新值。在上述情况下,如果更改映射值类型不是一个选项,那么首先执行“查找”以检查我们是否需要构造元素会更有效。
或者,可以更改映射的值类型,以使用您最喜欢的智能指针类型存储数据句柄。对 insert 的调用使用空指针(构造起来非常便宜),并且仅在必要时才构造新的数据类型。