The efficiency of different C++ constructs3

简介: The efficiency of different C++ constructs3

模板


模板与宏的相似之处在于,模板参数在编译之前被它们的值所替换

模板是高效的,因为模板参数总是在编译时被解析。模板使源代码更加复杂,而不是编译后的代码。一般来说,使用模板在 执行速度方面没有任何成本




使用模板实现编译时多态


模板类可用于实现编译时多态性,这比使用虚拟成员函数获得的运行时多态性更加高效

模板代码可读性不佳。如果编译器能够自动执行去虚拟化(去掉动态绑定时对虚函数表的查询), 那么依赖编译器优化肯定比使用这种复杂的模板方法更加方便。




线程


线程上下文切换非常耗时,可通过设置更长的时间片来减少上下文切换的次数。

为不同任务的不同线程分配不同的优先级是非常有用的


为了充分利用多核,我们将工作划分成多个线程,每个线程在单独的cpu core上执行。但是多线程有四个成本:


  • 启动和停止线程的成本。如果任务执行时间很短,不要为其单独分配线程


  • 线程切换成本。


  • 线程间同步和通信成本。


  • 不同线程需要单独的存储空间,线程有各自的堆栈,如果线程共享相同的缓存,可能会导致缓存竞争。



多线程程序必须使用线程安全函数,线程安全函数永远不应该使用静态变量(除非只读)




异常和错误处理


c++中通过try catch捕获异常。异常处理旨在检测很少发生的错误,并以一种优雅的方式从错误条件中恢复


虽然程序运行时没有错误,但是异常处理仍需要额外的时间,花销多少取决于编译器实现。


如果你的应用程序不需要异常处理,那么应该禁用它,以便使代码更小、更高效。你可以通过关闭编译器中的异常处理选项来禁 用整个程序的异常处理。你也可以通过向函数原型中添加 throw() 声明来禁用单个函数的异常处理:




异常和向量代码


向量指令对于并行执行多个计算是有用的。


如果代码可以从向量指令中获益,那么最好禁用异常捕获,转而依赖 NAN 和 INF 的传递。



避免异常处理的成本

当不需要尝试从错误中恢复时,不需要异常处理。


建议使用系统的、经过深思熟虑的方法来处理错误。你必须区分可恢复错误和不可恢复错误;确保分配的资源在发生错误时 得到清理;并向用户发送适当的错误消息。



编写异常安全代码


为了保证异常安全,需要在发生异常时清理资源


  • 使用new和malloc分配的内存


  • 句柄


  • 互斥量


  • 数据库连接


  • 网络连接


  • 待删除临时文件


  • 待保护的用户工作


  • 其他已分配的资源


C++ 处理清理工作的方法是创建一个析构函数。C++ 异常处理系统确保调用本地对象的所有析构函数。 如果包装器类有析构函数来处理分配资源的所有清理工作,则程序是异常安全的。如果析构函数引发另一个异常,则系统可能会出现问题。


如果你使用自己的错误处理系统而不是使用异常处理,那么你无法确保调用了所有析构函数并清理了资源。如果错误处理程 序调用 exit()、abort()、_endthread() 等,则不能保证所有析构函数被调用




NAN和INF的传递


浮点溢出和除以 0 得到无穷大。如果你把无穷大和某数相加或相乘,结果就是无穷大。 如果用一个正常的数字除以INF,会得到0 。特殊情况INF‐INF和INF/INF得到NAN (not‐a‐number)。当你用 0 除以 0 以及函数的输入超出范围时,比如sqrt(‐1)和log(‐1),也会出现 特殊的代码NAN。


INF 和 NAN 的传播也不需要额外的成本


当参数为 INF 或 NAN 时,函数 finite() 将返回 false,如果它是一个普通的浮点数,则返回 true。




预处理命令


就程序性能而言,预处理指令(以#开头的所有指令)的性能成本很少,因为它们在程序编译之前就已经解析了




命名空间


使用名称空间,对执行速度没有影响

相关文章
|
存储 缓存 并行计算
The efficiency of different C++ constructs5
The efficiency of different C++ constructs5
129 0
|
存储 缓存 编译器
The efficiency of different C++ constructs4
The efficiency of different C++ constructs4
114 0
|
存储 缓存 Unix
The efficiency of different C++ constructs2
The efficiency of different C++ constructs2
130 0
|
缓存 编译器 C++
The efficiency of different C++ constructs
The efficiency of different C++ constructs
136 0
|
3天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
17 2
|
9天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
35 5
|
15天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
46 4
|
16天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
43 4
|
2月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
28 4
|
2月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
25 4