条目二十四《当效率至关重要时,请在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来说,插入不存在的值,省略了三个函数的调用啊。
所以针对添加元素,insert比operator[]更高效。
再来看对于更新元素的情况。
m[k]=v
m.insert(map<int, TesyObj>::value_type(k, v)).first->second=v
从感官上看,前者肯定比后者简洁舒服啊。不过我们要看的是效率。
后者比前者多了对pair对象的构造和析构,而且在构造pair时又对v(TestObj)对象构造,析构pair时又对v析构,所以前者效率更高。。。
最后看个例子吧,一个鱼与熊掌兼得的实现:

条目二十四《当效率至关重要时,请在map::operator[]与map::insert之间谨慎做出选择》的更多相关文章
- (C/C++学习笔记) 二十四. 知识补充
二十四. 知识补充 ● 子类调用父类构造函数 ※ 为什么子类要调用父类的构造函数? 因为子类继承父类,会继承到父类中的数据,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程. ...
- 《条目二十九:对于逐个字符的输入请考虑istreambuf_iterator》
<条目二十九:对于逐个字符的输入请考虑istreambuf_iterator> 1.使用: ifstream inputfile("xxxx"); string fil ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...
- VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机
VMware vSphere 服务器虚拟化之二十四 桌面虚拟化之手动池管理物理机 VMwareView手动池可以管理物理计算机 说明: 环境基于实验二十三 1.准备一台Windows 7的物理计算机名 ...
- 二十四. Python基础(24)--封装
二十四. Python基础(24)--封装 ● 知识结构 ● 类属性和__slots__属性 class Student(object): grade = 3 # 也可以写在__slots ...
- 条目二十八《正确理解由reverse_iterator的base()成员函数所产生的iterator的用法》
条目二十八<正确理解由reverse_iterator的base()成员函数所产生的iterator的用法> 迭代器的种类一共有四种,上面已经说过了.这里就不再次写出来. 这一个条目主要是 ...
- 条目二十六《iterator优先于const_iterator、reverse_iterator以及const_reverse_iterator》
条目二十六<iterator优先于const_iterator.reverse_iterator以及const_reverse_iterator> 这几个东西不是类型来的,而是不同的类,所 ...
- 微信小程序把玩(二十四)toast组件
原文:微信小程序把玩(二十四)toast组件 toast消息提示框,可用在提示一些信息,比如清楚缓存给用户一个友好的提示!或操作一些请求不想让用户有什么操作,toast也可以做到因为toast显示时其 ...
随机推荐
- OC中数组排序总结
过完节回来,感觉很多东西都生疏了.总结一下数组的排序.应该不会太完美,后续添加补充. OC中的数组排序方法其实不太多,要根据不同的使用场景来使用不同的方法.Foundation框架中一般用到一下几个方 ...
- linux系统文件的链接
一. 硬链接(实际链接) (以linux系统为例) 1. 文件的索引节点inode 假设我们在硬盘当前目录下建立了一个名为mytext文本文件,其内容只有一行:This is my file. (1) ...
- LINK : fatal error LNK1104: cannot open file "mfc42d.lib"
VC++6.0上建立了个基于MFC应用程序,在编译时候没出现错误,但在LINK的是时候出现这样的错误:Linking...LINK : fatal error LNK1104: cannot open ...
- Zedboard学习(三):PL下流水灯实验 标签: fpgazynqPL 2017-07-05 11:09 21人阅读 评论(0)
zynq系列FPGA分为PS部分和PL部分. PL: 可编程逻辑 (Progarmmable Logic), 就是FPGA部分. PS: 处理系统 (Processing System) , 就是与F ...
- 解决ImportError: libmysqlclient_r.so.16: cannot open shared object file-乾颐堂
在开发一个python项目是,需要用到mysql,但是, 安装完mysql-python后import加载模块提示以下错误: ImportError: libmysqlclient_r.so.16: ...
- [Training Video - 4] [Groovy] Function in detail
Employee.log=log Employee e1 = new Employee() Employee e2 = new Employee() e1.name = "A" e ...
- Python3+Apache+Django+CentOS
使用django开发的项目上到正式环境的环境搭建,系统软件版本: CentOS6. setuptools-.tar.gz pip-.tar.gz Python-.tgz pcre-8.39.tar.b ...
- soapUI的bug切换版本解决
目录 文章背景 目录 运行环境及出现的问题 问题解决 说明 参考文章 版本记录 文章背景 为公司编写了一个webservice,本地测试时候是没有问题的,发布到现场之后,访问出现异常,通过切换soap ...
- jenkins构建后接受者收不到邮件问题解决方案
jenkins部署.安装增强版邮件插件,配置邮件及增强版邮件通知请参考网上教程,由于教程比较多页通俗易懂,笔者在这里不做重复说明,本文重点是解决配置好增强版邮件,job构建后仍然收不到邮件的问题 步骤 ...
- 软件加license的一种实现方法
以前从没干过破解的勾当,这次确实必须要去破解一个,于是下了个反编译工具. 最终拿到反编译出来的文件,欣赏了一把它的license检测代码.原谅我的无知,以下代码在我看来还是比较新鲜,犬神请不要鄙视: ...