• 条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》


    条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》

    当效率至关重要时,应该在map::operator[]map::insert之间仔细做出选择。如果要更新一个已有的映射表元素,则应该优先选择operator[];但如果要添加一个新的元素,那么最好还是选择insert

    下面来分析为什么是这样子的。

    首先先说明,下面两个式子是等价的:

    map<int, int> ss;
    ss[1]=2    //式子1
    ss.insert(pair<int, int>(1, 2))  //式子2
    

    咋一看上去,式子1比式子2简洁很多,但二者在不同情况下性能是不一样的。

    map::operator[] 返回一个引用,它指向与k相关联的值对象。然后v被赋给该引用(operator[]返回的那个引用)所指向的对象。如果键k已经有了相关联的值,则该值被更新。如果k还没有在映射表中,那就没有operator[]可以指向的值对象。在这种情况下,它使用值类型的默认构造函数创建一个新的对象,然后operator[]就能返回一个指向该新对象的引用了。

    对于第二种情况,就是说,如果map::operator[]的是一个不存在map的值,会先调用默认构造函数创建一个临时对象,然后对得到的临时对象的引用的对象调用赋值函数(修改v),最后调用析构函数析构临时对象。

    你看这里会经历三个函数的调用哦,所以如果是频繁的经历这个过程,肯定会对性能有影响的。

    pair<map<int, TesyObj>:: itrator, bool> iesult = m.insert(map<int, TesyObj>>:: value_type(1, TestObj())
    result.first->second=5
    

    上面的代码例子就是上面说的过程囖。

    再看map::insert的情况。
    m.insert(map<int, TesyObj>::value_type(1, 5))
    你看,对于map::insert来说,插入不存在的值,省略了三个函数的调用啊。

    所以针对添加元素insertoperator[]更高效。

    再来看对于更新元素的情况。

    m[k]=v
    m.insert(map<int, TesyObj>::value_type(k, v)).first->second=v
    

    从感官上看,前者肯定比后者简洁舒服啊。不过我们要看的是效率。

    后者比前者多了对pair对象的构造析构,而且在构造pair时又对v(TestObj)对象构造,析构pair时又对v析构,所以前者效率更高。。。

    最后看个例子吧,一个鱼与熊掌兼得的实现:

    ![](file:///storage/emulated/0/Pictures/ddReader/1547478826150.png)

  • 相关阅读:
    BZOJ-2462: [BeiJing2011]矩阵模板 (宇宙无敌超级大暴力~)
    BZOJ-3555: [Ctsc2014]企鹅QQ (hash)
    BZOJ-3098: Hash Killer II (未知)
    [SinGuLaRiTy] 2017 百度之星程序设计大赛 初赛A
    [SinGuLaRiTy] 树链问题
    [SinGuLaRiTy] 2017 百度之星程序设计大赛-资格赛
    [SinGuLaRiTy] NOIP模拟赛(TSY)-Day 2
    [SinGuLaRiTy] NOIP模拟赛(TSY)-Day 1
    [SinGuLaRiTy] 2017-07-26 综合性测试
    [SinGuLaRiTy] NOIP 膜你赛-Day 2
  • 原文地址:https://www.cnblogs.com/liangjf/p/10275039.html
Copyright © 2020-2023  润新知