C++ 性能剖析 (四):Inheritance 对性能的影响,剖析inheritance
(这个editor今天有毛病,把我的format全搞乱了,抱歉!)
Inheritance 是OOP 的一个重要特征。虽然业界有许多同行不喜欢inheritance,但是正确地使用inheritance是一个应用层面和架构层面的重要设计决定。 大量使用inheritance,尤其在类似std container 中使用,会对程序性能产生何等影响呢?
从我个人的经验来看,constructor对创建具有深层inheritance链的class,有很大的影响。 如果应用容许,最好使用没有constructor的基类。下面举个例子:
struct __declspec(novtable) ITest1
{ virtual void AddRef() = 0;
virtual void Release() = 0;
virtual void DoIt(int x) = 0; };
class CTest: public ITest1
{
int ref;
public: inline CTest() { ref = 0; }
inline void AddRef() { ++ref; }
inline void Release() {--ref; }
inline void DoIt(int x) {ref *= x; }
inline void AddRef2() { ++ref; }
inline void Release2() {--ref; }
inline void DoIt2(int x) {ref *= x; }
static void TestPerf(int loop); };
这是个dummy程序,然而在COM中确是再常见不过。如果我们要大量创建并使用CTest,有经验的程序员应该看出,ITest1 完全不需要constructor。 根据C++ 说明书,ITest1因为有虚拟函数,属于“非简单构造类”,编译必须产生一个constructor,其唯一的目的是设置ITest1的vtbl (虚拟函数表)。
然而interface的唯一作用是被继承,所以其vtbl一定是被其继承类设置。编译在这种情况下没必要生成constructor。 微软在设计ATL时认识到这一点,推出自己的方案来躲避C++官方SPEC的缺陷:VC++提供了novtable的class modifier,告诉编译:我不需要你的constructor. 然而我在VS 2010中的测试结果却令人失望:
ITest1的constructor 仍然被生成了,只是它没有将vtbl赋值而已,这对增进基类构造的性能实为杯水车薪之举。 下面我们看看这个“毫无用处的constructor”对性能的影响。 我们权且拿出另一个不需要虚拟函数的ITestPOD (POD的意思是“数据而已”)来做比较:
struct ITest1POD
{ inline void AddRef() { }
inline void Release() { }
inline void DoIt(int x) { } };
ITestPOD当然不能完全作interface用(interface必须用虚拟函数),仅仅为了测试。然后,我们设计一个继承类,和上面的CTest功能完全一样:
class CTestPOD: public ITest1POD
{
int ref;
public: inline CTestPOD() { ref = 0; }
inline void AddRef() { ++ref; }
inline void Release() {--ref; }
inline void DoIt(int x) {ref *= x; }
};
我们的目的是用这个CTestPOD来和CTest作一番苹果与苹果的比较:
void CTest::TestPerf(int loop)
{
clock_t begin = clock();
for(int i = 0; i
{
CTestPOD testPOD; // line1
testPOD.AddRef();
testPOD.DoIt(0);
testPOD.Release();
}
clock_t end = clock();
printf("POD time: %f \n",double(end - begin) / CLOCKS_PER_SEC);
begin = clock();
for(int i = 0; i
{
CTest test; // line2
test.AddRef2();
test.DoIt2(0);
test.Release2();
}
end = clock();
printf("Interface time: %f \n",double(end - begin) / CLOCKS_PER_SEC);
}
上面的loop1和loop2的唯一区别在line1和line2,为了避免用虚拟函数,我特意给CTest准备了AddRef2,DoIt2,Release2,三个同样的但却是非虚拟的函数,为的是遵循性能测试的一大原理:compare apple to apple。
我将loop设为10万,测试结果显示,loop2比loop1的速度低了20% 左右。从生成的代码来看,唯一的区别是CTest的constructor调用了编译自动生成的ITest1 的constructor。这个constructor没有任何作用,却白占了许多CPU周期。一个好的编译,应该是可以把这个constructor裁剪掉的,这个靠我们自己去搜索了。
总结
在应用inheritance时,除去基类里无用的constructor,对大量构造的object的性能来说,会有明显的影响。不幸的是,微软的__declspec(novtable) class modifier对解决这个问题没有提供任何帮助。在设计海量存储的object的应用中,我们应该尽量用POD来做其基类,避免上面CTest类那样明显的性能漏洞。
2014-9-3 西雅图
在所有的固体中,原子靠键结合在一起。键使固体具有强度和相应的电学和热学性能。例如,强的键导致高熔点、高弹性模量、较短的原子间距和较低的热膨胀系数。
一、化学键
1. 离子键
离子键是由正负电荷的相互吸引造成的。例如,钠原子的价轨道中有一个电子,它很容易将外层电子释放而成为带正电的离子。同样,氯原子容易接受一个电子进入它们的价轨道直至达到八个电子而成为带负电的离子。既然带负电和带正电的材料之间总存在静电引力,那么在带不同电荷的相邻离子间就形成了键。离子键的特点是与正离子相邻的是负离子,与负离子相邻的是正离子,如NaCl晶体,见图2-1。
2 共价键
共价键是一种强吸引力的结合键。当两个相同原子或性质相近的原子接近时,价电子不会转移,原子间借共用电子对所产生的力而结合,形成共价键。共价键使原子间有很强的吸引力,这一点在金刚石中很明显,金刚石是自然界中最硬的材料,而且它完全是由碳原子组成。每个碳原子有四个价电子,这些价电子与邻近原子共用,形成完全由价电子对结合而成的三维点阵。这些三维点阵使金刚石具有很高的硬度和熔点。
3. 金属键
金属是由金属键结合而成的,它具有同非金属完全不同的特性。金属原子的外层电子少,容易失去。当金属原子相互靠近时,这些外层原子就脱离原子,成为自由电子,为整个金属所共有,自由电子在金属内部运动,形成电子气。这种由自由电子与金属正离子之间的结合方式称为金属键,见图2-2。4. 分子键
分子键又叫范德瓦尔斯键,是最弱的一种结合键。它是靠原子各自内部电子分布不均匀产生较弱的静电引力,称为范德瓦尔斯力,由这种分子力结合起来的键叫做分子键。
5. 氢键
另一种范德瓦尔斯力实际上是极性分子的一种特殊情况。C-H、O-H或N-H键端部暴露的质子是没有电子屏蔽的,所以,这个正电荷可以吸引相邻分子的价电子,于是形成了一种库仑型的键,称为氢键,氢键是所有范德瓦尔斯键中最强的。氢键最典型的例子是水,一个水分子中氢质子吸引相邻分子中氧的孤对电子,氢键使水成为所有低分子量物质中沸点最高的物质。
二、结合键对材料性能的影响
1. 金属材料
金属材料的结合键主要是金属键。由于自由电子的存在,当金属受到外加电场作用时,其内部的自由电子将沿电场方向作定向运动,形成电子流,所以金属具有良好的导电性;金属除依靠正离子的振动传递热能外,自由电子的运动也能传递热能,所以金属的导热性好;随着金属温度的升高,正离子的热振动加剧,使自由电子的定向运动阻力增加,电阻升高,所以金属具有正的电阻温度系数;当金属的两部分发生相对位移时,金属的正离子仍然保持金属键,所以具有良好的变形能力;自由电子可以吸收光的能量,因而金属不透明;而所吸收的能量在电子回复到原来状态时产生辐射,使金属具有光泽。
金属中也有共价键(如灰锡)和离子键(如金属间化合物Mg3Sb2)。
2. 陶瓷材料
简单说来,陶瓷材料是包含金属和非金属元素的化合物,其结合键主要是离子键和共价键,大多数是离子键。离子键赋予陶瓷材料相当高的稳定性,所以陶瓷材料通常具有极高的熔点和硬度,但同时陶瓷材料的脆性也很大。
3. 高分子材料
高分子材料的结合键是共价键、氢键和分子键。其中,组成分子的结合键是共价键和氢键,而分子间的结合键是范德瓦尔斯键。尽管范德瓦尔斯键较弱,但由于高分子材料的分子很大,所以分子间的作用力也相应较大,这使得高分子材料具有很好的力学性能。
三、晶体与非晶体
在研究了结合键后,我们下一步的任务就是从原子或分子的排列方式上考虑材......余下全文>>
玻璃幕墙新规范、工程检验标准的
探讨和介绍
山东省建筑科学研究院(山东省建设机械质量监督检测中心)
李 承 伟
山东省建设机械质量监督检测中心作为我省的专职建筑幕墙检测单位,同时也作为国家工业产品生产许可证指定检测单位,近年来,对我省建筑幕墙工程进行了长期的测试和跟踪调查,初步掌握了我省建筑幕墙工程制造质量和施工水平的第一手资料。对比国内先进企业的技术水平,我省幕墙企业不仅在生产技术水平上存在一定的差距,同时,在对建筑幕墙的技术设计和施工手段上也存在一定的距离,重点反映在对规范的理解和贯彻上存在较大的差距。下面,就针对建筑幕墙的设计、计算及对规范的理解等方面,谈一下我们的看法。
一、《玻璃幕墙工程技术规范》JGJ102-2003修订内容概述
《玻璃幕墙工程技术规范》JGJ102-2003自2004年1月1日起实施,原行业标准《玻璃幕墙工程技术规范》JGJ102-96同时废止。JGJ102-2003修订内容较大,不仅增加了强制性条款、而且还增加了全玻幕墙及点支承幕墙内容、对其他内容也进行了较大的修订。
(一)增加的强制性条款:
1、硅酮结构密封胶在隐框和半隐框玻璃幕墙中使用,其玻璃与铝型材的粘结必须采用中型硅酮结构密封胶。
硅酮结构密封胶使用前,应经国家认可的检测机构进行与其相接触材料的相容性和剥离粘结性试验,并应对邵氏硬度、标准状态下拉伸粘结性能进行复验。检验不合格的产品不得使用。进口硅酮结构密封胶应具有商检报告。硅酮结构密封胶和硅酮建筑密封胶必须在有效期内使用。
硅酮结构密封胶应根据不同的受力情况进行承载力极限状态验算。
除全玻幕墙外,不应在现场打注硅酮结构密封胶。
2、结构件应按规定验算承载力和挠度并达到规范要求。
立柱主要受力部位铝型材截面开口部位的厚度不应小于3.0mm,闭口部位的厚度不应小于2.5mm;型材孔壁与螺钉之间直接采用螺纹受力连接时,其局部厚度尚不应小于螺钉的公称直径;钢型材截面主要受力部位的厚度不应小于3.0mm。
横梁主要受力部位铝合金型材的厚度不应小于2.0mm;当横梁跨度大于1.2 m时,其截面主要受力部位的厚度不应小于2.5mm。型材孔壁与螺钉之间直接采用螺纹受力连接时,其局部截面厚度不应小于螺钉的公称直径。钢型材截面主要受力部位的厚度不应小于2.5mm。
3、人员流动密度大、青少年或幼儿活动的公共场所以及使用中容易受到撞击的部位,其玻璃幕墙应采用安全玻璃;对使用中容易受到撞击的部位,尚应设置明显的警示标志。
(二)全玻幕墙的主要内容:
面板玻璃的厚度不宜小于10mm,当面板玻璃为夹层玻璃时,其单片厚度不应小于8 mm。
玻璃肋的截面厚度不应小于12mm,截面高度不应小于100mm。而且,该条为强制性条款。
在风荷载标准值作用下,玻璃肋的挠度限值宜取其计算跨度的1/200。
采用浮头式连接件的幕墙玻璃厚度不应小于6 mm;采用沉头式连接件的幕墙玻璃厚度不应小于8 mm。玻璃之间的空隙宽度不应小于10 mm,且应采用硅酮建筑密封胶嵌缝。该部分为强制性条款。
点支承玻璃幕墙的支承结构宜单独进行计算。
无论单根型钢或钢管作为支承结构、采用桁架或空腹桁架作为支承结构,在风荷载标准值作用下,其挠度极限宜取其跨度的1/250。
张拉杆索体系应在正反两个方向上形成承受风荷载或地震作用的稳定结构体系,连接件、受压杆或拉杆宜采用不锈钢材料,杆件直径不宜小于10mm,拉索钢绞线直径不宜小于8 mm。拉杆不宜采用焊接,拉索不应采用焊接。在风荷载标准值作用下,其挠度极限宜取其跨度......余下全文>>

C++是一种广泛使用的面向对象的计算机编程语言,它支持您与之交互的大多数应用程序和网站。你需要编译器和集成开发环境来开发C++应用程序,既然你在这里,我猜你正在寻找一个。我们将在本文中介绍一些适用于Windows11的C++编译器的主要推荐。许多审查的编译器将主要用于C++,但也有许多通用编译器您可能想尝试。MinGW可以在Windows11上运行吗?在本文中,我们没有将MinGW作为独立编译器进行讨论,但如果讨论了某些IDE中的功能,并且是DevC++编译器的首选

在C++程序开发中,当我们声明了一个变量但是没有对其进行初始化,就会出现“变量未初始化”的报错。这种报错经常会让人感到很困惑和无从下手,因为这种错误并不像其他常见的语法错误那样具体,也不会给出特定的代码行数或者错误类型。因此,下面我们将详细介绍变量未初始化的问题,以及如何解决这个报错。一、什么是变量未初始化错误?变量未初始化是指在程序中声明了一个变量但是没有

C++是一门广受欢迎的编程语言,但是在使用过程中,经常会出现“未定义的引用”这个编译错误,给程序的开发带来了诸多麻烦。本篇文章将从出错原因和解决方法两个方面,探讨“未定义的引用”错误的解决方法。一、出错原因C++编译器在编译一个源文件时,会将它分为两个阶段:编译阶段和链接阶段。编译阶段将源文件中的源码转换为汇编代码,而链接阶段将不同的源文件合并为一个可执行文

如何优化C++开发中的文件读写性能在C++开发过程中,文件的读写操作是常见的任务之一。然而,由于文件读写是磁盘IO操作,相对于内存IO操作来说会更为耗时。为了提高程序的性能,我们需要优化文件读写操作。本文将介绍一些常见的优化技巧和建议,帮助开发者在C++文件读写过程中提高性能。使用合适的文件读写方式在C++中,文件读写可以通过多种方式实现,如C风格的文件IO

C++是一门强大的编程语言,它支持使用类模板来实现代码的复用,提高开发效率。但是在使用类模板时,可能会遭遇编译错误,其中一个比较常见的错误是“无法为类模板找到实例化”(error:cannotfindinstantiationofclasstemplate)。本文将介绍这个问题的原因以及如何解决。问题描述在使用类模板时,有时会遇到以下错误信息:e

iostream头文件包含了操作输入输出流的方法,比如读取一个文件,以流的方式读取;其作用是:让初学者有一个方便的命令行输入输出试验环境。iostream的设计初衷是提供一个可扩展的类型安全的IO机制。

c++初始化数组的方法:1、先定义数组再给数组赋值,语法“数据类型 数组名[length];数组名[下标]=值;”;2、定义数组时初始化数组,语法“数据类型 数组名[length]=[值列表]”。

C++是一种流行的编程语言,它强大而灵活,适用于各种应用程序开发。在使用C++开发应用程序时,经常需要处理各种信号。本文将介绍C++中的信号处理技巧,以帮助开发人员更好地掌握这一方面。一、信号处理的基本概念信号是一种软件中断,用于通知应用程序内部或外部事件。当特定事件发生时,操作系统会向应用程序发送信号,应用程序可以选择忽略或响应此信号。在C++中,信号可以


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

WebStorm Mac 버전
유용한 JavaScript 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

뜨거운 주제



