The efficiency of different C++ constructs2

简介: The efficiency of different C++ constructs2

函数参数


在大多数情况下,函数参数是按值传递的。这意味着参数的值被复制到一个局部变量中。对于int、float、double、bool、enum 以及指针和引用等简单类型,这非常快。

数组总是使用指针传递,除非它们被打包在类或者结构体中。



如果参数是复合类型,在以下情况下传值更高效,否则使用指针和引用更高效

  • 对象很小,可以装入一个寄存器


  • 对象没有拷贝构造函数和析构函数


  • 对象没有虚成员


  • 对象没有使用RTTI


将复合对象传递给函数的首选方法是使用const引用。其次是使函数成为对象的类成员

64位unix系统允许寄存器中传输最多14个参数(8个float或double, 加上6个整数、指针或引用参数)



函数返回类型


函数的返回类型最好是简单类型、指针、引用或 void。返回复合类型的对象更为复杂,而且常常效率低下。


简单情况下,复合类型对象直接从寄存器返回。否则通过一个隐藏指针将它们复制到调用方指定的位置。


当直接返回复杂类型对象的值时,编译器可能会进行RVO(return value optimization)优化,从而避免复制构造和析构成本,但开发者不应依赖这一点。




函数尾调用


尾调用是优化函数调用的一种方法。如果函数的最后一条语句是对另一个函数的调用,那么编译器可以用跳转到第二个函数 来替换该调用。 优化编译器将自动完成此任务。第二个函数不会返回到第一个函数,而是直接返回第一个函数被调用的位 置。这样效率更高,因为它消除了返回操作。




递归函数


函数递归调用对于处理递归数据结构非常有用。递归函数的代价是所有参数和局部变量在每次递归时都会有一个新实例,这会占用栈空间。


较宽的树形结构比较深的树形结构,有更高的递归效率 .


无分支递归总是可以用循环代替,这样的效率更高




结构体和类


面向对象的好处


  • 变量存储在一起,数据缓存更有效率


  • 无需将类成员变量作为参数传递给类成员函数,避免参数传递的开销

面向对象的坏处:



  • 非静态成员函数有this指针,有额外开销


  • 虚成员函数的效率较低


如果面向对象的编程风格有利于程序的逻辑结构和清晰性,那么你可以使用这种风格




类的数据成员


类或结构体的数据成员是按创建类或结构实例时声明它们的顺序连续存储。将数据组织到类或结构体中不存在性能损失。


大多数编译器将数据成员对齐到可以被特定数整除的地址以优化访问,副作用是产生字节空洞



类的成员函数


每次声明或创建类的新对象时,它都会生成数据成员的新实例。但是每个成员函数只有一个实例。函数代码不会被复制


静态成员函数不能访问任何非静态数据成员或非静态成员函数。静态成员函数比非静态成员函数快。



虚成员函数


多态性是面向对象程序比非面向对象程序效率低的主要原因之一。 如果可以避免使用虚函数,那么你就可以获得面向对象编程的大多数优势,而无需付出性能成本 。


如果函数调用语句总是调用虚函数的相同版本,那么调用虚成员函数所花费的时间要比调用非虚成员函数多几个时钟周期。 如果版本发生了变化,你可能会得到10 ‐ 20个时钟周期的错误预测惩罚。


有时可以使用模板而不是虚函数来获得所需的多态性效果。




运行时类型识别(RTTI)


效率不高。如果编译器有RTTI 选项,那么关闭它并使用其他实现。


继承


派生类的对象与包含父类和子类成员的简单类的对象的实现方法相同。父类和子类的成员访问速度相同。一般来说,你可以 假设使用继承几乎没有任何性能损失。


除了

  • 父类数据成员大小会添加到子类成员的偏移量中。偏移量太大时,会造成数据缓存效率降低


  • 父类和子类代码可能在不同模块。造成代码缓存效率降低


尽量不使用多重继承,代之以组合



联合体


union 是数据成员共享相同内存空间的结构。union 可以通过允许从不同时使用的两个数据成员共享同一块内存来节省内存 空间。




位域


位域可能有助于使数据更加紧凑。访问位域成员不如访问结构的成员效率高。如果在大数组可以节省缓存空间或使文件更 小,那么额外的时间是合理的




重载函数


重载函数的不同版本被简单地视为不同的函数。使用重载函数没有性能损失




重载运算符


重载的运算符相当于一个函数。使用重载运算符与使用具有相同功能的函数效率一样

相关文章
|
存储 缓存 并行计算
The efficiency of different C++ constructs5
The efficiency of different C++ constructs5
192 0
|
存储 缓存 编译器
The efficiency of different C++ constructs4
The efficiency of different C++ constructs4
197 0
|
缓存 安全 编译器
The efficiency of different C++ constructs3
The efficiency of different C++ constructs3
204 0
|
缓存 编译器 C++
The efficiency of different C++ constructs
The efficiency of different C++ constructs
241 0
|
9月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
156 0
|
5月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
239 0
|
7月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
281 12
|
8月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
171 16
|
9月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)