std::map insert or std::map find?

后端 未结 8 1378
青春惊慌失措
青春惊慌失措 2020-12-12 08:41

Assuming a map where you want to preserve existing entries. 20% of the time, the entry you are inserting is new data. Is there an advantage to doing std::map::find then std

8条回答
  •  臣服心动
    2020-12-12 09:26

    The answer to this question also depends on how expensive it is to create the value type you're storing in the map:

    typedef std::map  MapOfInts;
    typedef std::pair  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;
      }
    }
    

    For a value type such as an int, the above will more efficient than a find followed by an insert (in the absence of compiler optimizations). As stated above, this is because the search through the map only takes place once.

    However, the call to insert requires that you already have the new "value" constructed:

    class LargeDataType { /* ... */ };
    typedef std::map  MapOfLargeDataType;
    typedef std::pair  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;
      }
    }
    

    In order to call 'insert' we are paying for the expensive call to construct our value type - and from what you said in the question you won't use this new value 20% of the time. In the above case, if changing the map value type is not an option then it is more efficient to first perform the 'find' to check if we need to construct the element.

    Alternatively, the value type of the map can be changed to store handles to the data using your favourite smart pointer type. The call to insert uses a null pointer (very cheap to construct) and only if necessary is the new data type constructed.

提交回复
热议问题