C++ 性能剖析 (二):值语义 (value semantics)
Value Semantics (值语义) 是C++的一个有趣的话题。
什么是值语义? 简单的说,所有的原始变量(primitive variables)都具有value semantics. 也可以说,它们可以对应传统数学中的变量。有人也称它为POD (plain old data), 也就是旧时的老数据(有和 OOP 的新型抽象数据对比之意)。
对一个具有值语义的原始变量变量赋值可以转换成内存的bit-wise-copy。
对于用户定义的类呢?我们说,如果一个type X 具有值语义, 则:
1)X 的size在编译时可以确定。
这一点看似自然,其实在C++里有许多变量的size编译时无法确定。比如我在reference 三位一体里提到的polymorphic 变量,因为是“多身份”的,其(内容)的size是动态的。
2)将X的变量x,赋值与另一个变量y,无须专门的 = operator,简单的bit-wise-copy 即可。
3)当上述赋值发生后,x和y脱离关系:x 和 y 可以独立销毁, 其内存也可以独立释放。
了解第三点很重要,比如下面的class A就不具备值语义:
class A
{
char * p;
public:
A() { p = new char[10]; }
~A() { delete [] p; }
};
A 满足1和2,但不满足3。因为下面的程序会出错误:
Foo()
{
A a;
A b = a;
} // crash here
改进的方法是定义一个A::operator=(constA &),并且用reference counting 的技术来保护指针,实现起来并不简单。所以我们说一旦一个class 失去了value semantics, 它也就失去了简单明了的 = 语义。
从上面的分析可以得出结论,value semantics 有个简单的 = , 也正是数学意义上的 = 。
学过Java, C#, 和JavaScript的程序员都知道,这些语言里的object都不具有值语义,因为它们都是指针,= 并不copy内容。也不满足条件3。
那么value semantics 对C++性能有什么影响呢?我觉得有以下几方面:
1)std 库是基于值语义 的。std container 包含的元素,都具有值语义. 不理解这一点,就不能正确使用std,也不会对std的性能,做出合理预期。
2)简单的bit-wise-copy 赋值语句一般会提高赋值性能,因为它不需要特殊的 = operator 了。在使用std container 时,会有大量的copy 或assignment。 bit-wise-copy对于小的变量通常比函数划算得多。
3)具有值语义的,size 不大的变量,在stack里,作为auto变量,传递,拷贝,释放全部和原始变量的用法完全一致,既好用,一般也具有优良的性能。动态语言缺乏这个(值语义)的语言构造和能力,(C# 有有限地支持:c# struct),所以速度上很难优化。
4)注意,在设计具有值语义的类时,不要保留无用的destructor. destructor 的存在,使得你的类的语义和原始类有了本质的区别,C++ 编译会为此处心积虑地添加管理代码,使得一个简单的函数复杂化(会专门著文论证), 并且严重影响性能。这些当然是有附加值的,但是必须是设计需求的,而不是简单照搬的。
5)不要保留无用的destructor这点,对使用 std 时更重要。我会专门论述。不要有臃余无用的 destructor 对任何类都是适用的,而对于有大量 copy, assignment 的 std container 尤为重要!
那么,什么样的类没有值语义呢?我们不妨称这种型为 none-value-semantics type (NVST).
1)有virtual function 的类
2)包含NVST成员的类
3)NVST 的衍生类(derived classed)
4)定义了自己的 = operator 的类
5)继承 virtual 基类的衍生类
2014-6-21 西雅图
C++ 性能剖析 (二):值语义 (value semantics)的更多相关文章
- 快速学习C语言二: 编译自动化, 静态分析, 单元测试,coredump调试,性能剖析
上次的Hello world算是入门了,现在学习一些相关工具的使用 编译自动化 写好程序,首先要编译,就用gcc就好了,基本用法如下 gcc helloworld.c -o helloworld.o ...
- EMW 性能优化二之---并发配置
EMW 性能优化二之---并发配置 在前一个日志中写到交货的异步更新,对于RFUI RF的前台操作会提升效率,异步更新不用等待更新状态的返回,启用更新队列的方式执行(SM13). 下面再补全性能相关的 ...
- PDF.NET开发框架性能剖析
PDF.NET开发框架性能剖析 前俩天发布了 关于PDF.NET开发框架对Mysql Sqlite PostgreSQL数据库分页支持的个人看法 ,说明了本人对框架的一些介绍和看法.今天我们一起思考一 ...
- MySQL性能剖析工具(pt-query-digest)【转】
这个工具同样来自percona-toolkit 该工具集合的其他工具 MySQL Slave异常关机的处理 (pt-slave-restart) 验证MySQL主从一致性(pt-table-chec ...
- Wellner 自适应阈值二值化算法
参考文档: Adaptive Thresholding for the DigitalDesk.pdf Adaptive Thresholding Using the Integral I ...
- 对象语义与值语义、资源管理(RAII、资源所有权)、模拟实现auto_ptr<class>、实现Ptr_vector
一.对象语义与值语义 1.值语义是指对象的拷贝与原对象无关.拷贝之后就与原对象脱离关系,彼此独立互不影响(深拷贝).比如说int,C++中的内置类型都是值语义,前面学过的三个标准库类型string,v ...
- 二值法方法综述及matlab程序
在某些图像处理当中一个关键步是二值法,二值化一方面能够去除冗余信息,另一方面也会使有效信息丢失.所以有效的二值化算法是后续的处理的基础.比如对于想要最大限度的保留下面图的中文字,以便后续的定位处理. ...
- adaptiveThreshold自适应二值化源码分析
自适应二值化介绍: 二值化算法是用输入像素的值I与一个值C来比较,根据比较结果确定输出值. 自适应二值化的每一个像素的比较值C都不同,比较值C由这个像素为中心的一个块范围计算在减去差值delta得到. ...
- XNOR-Net:二值化卷积神经网络
https://www.jianshu.com/p/f9b015cc4514 https://github.com/hpi-xnor/BMXNet BMXNet:基于MXNet的开源二值神经网络实现 ...
随机推荐
- Topk引发的一些简单的思考
软件工程课程的一个题目:写一个程序,分析一个文本文件中各个词出现的频率,并且把频率最高的10个词打印出来.文本文件大约是30KB~300KB大小. 首先说一下这边的具体的实现都是在linux上实现的. ...
- VM虚拟机上 实现CentOS 6.X下部署LVS(NAT)+keepalived实现高性能高可用负载均衡
一.简介 VS/NAT原理图: 二.系统环境 实验拓扑: 1 准备工作 a) 虚拟机上安装CentOS6.x操作系统,参考一下博客内容 http://www.cnblogs.com/seesea125 ...
- 国内大学毕业论文LaTeX模板集合
国内大学毕业论文LaTeX模板集合 薛瑞尼的清华大学学位论文LaTeX模板http://sourceforge.net/projects/thuthesis/ 北大论文文档 LaTeX 模板 pkut ...
- Walls POJ 1161
参考了大牛的博客 http://blog.csdn.net/wangjian8006/article/details/7958838 题目大意: 给出n个点,在这些点中有些点是俱乐部点,并且有m个区域 ...
- 2. Singleton模式
这两种方法都提到了使用模版: (1) 参考文章:http://www.cnblogs.com/08shiyan/archive/2012/03/16/2399617.html 不同: a. 该方法直接 ...
- cf590A Median Smoothing
A. Median Smoothing time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 谷歌 google
google Google是搜索引擎名,也是一家美国上市公司名称.Google公司于1998年9月7日以私有股份公司的形式创立,以设计并管理一个互联网的搜索引擎.Google公司的总部称作“Googl ...
- openstack 使用集锦
- [转载]使用uiautomator做UI测试
这个只是单纯的mark一下.还没有认真去研究.鉴于最近也不会做手机的自动化测试,所以留作以后参考吧. 转自: http://blog.chengyunfeng.com/?p=504 在Android ...
- Android应用开发学习之图片切换器
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 如果我们要实现类似Windows的照片查看器切换上一张下一张照片的效果,可以使用图片切换器ImageSwitcher ...