C++核心指导原则: 哲学部分

C++ Core Guidelines 是由 Bjarne Stroustrup 与其他专家共同制定的一系列关于如何高效, 安全地使用 C++的指导原则.
在 C++ Core Guidelines 的 Philosophy§部分, 提供了关于编写高质量, 可维护和安全的 C++代码的高层次指导原则.

C++ Core Guidelines 整理目录

  1. 哲学部分
  2. 接口(Interface)部分
  3. 函数部分
  4. 类和类层次结构部分
  5. 枚举部分
  6. 资源管理部分
  7. 表达式和语句部分
  8. 性能部分
  9. 并发和并行
  10. 错误处理
  11. 常量和不可变性
  12. 泛型编程
  13. 源文件
  14. 命名和布局建议
  15. 标准库
  16. 其他规则

P: Philosophy

P.1: Express ideas directly in code

  • 翻译: 直接在代码中表达想法.
  • 原因: 清晰明了的代码更容易理解和维护. 通过使用有意义的变量名和函数名, 可以减少注释的需求.
class Date {
  // ...
 public:
  Date(Year year, Month month, Day day);  // good
  Date(int year, int month, int day);     // bad
};

比如这个示例中, 使用 Year, MonthDay 来构造 Date 对象, 而不是使用 int 作为参数. 连续三个 int 类型的参数很容易出现传参错误而且编译器无法发现. 而使用强类型则可以最大程度上避免传参错误.

int index = -1;  // bad
for (int i = 0; i < v.size(); ++i) {
  if (v[i] == target) {
    index = i;
    break;
  }
}
auto it = std::find(begin(v), end(v), target);  // better

使用 std::find 而不是 for 循环, 可以更好的表达意图.

P.2: Write in ISO standard C++

  • 翻译: 使用 ISO 标准 C++编写代码.
  • 原因: 遵循标准可以确保代码的可移植性和兼容性, 避免依赖特定编译器的行为. 同样需要避免未定义行为.

P.3: Use libraries wherever possible

  • 翻译: 尽可能使用库.
  • 原因: 库通常经过广泛测试和优化, 使用它们可以提高代码质量和性能, 并减少重复劳动.

P.4: Avoid writing new code when a library can do the job

  • 翻译: 当库可以完成任务时, 避免编写新代码.
  • 原因: 重用现有库可以减少错误, 提高开发效率, 并利用已经存在的优化. 用自己造的轮子容易翻车.

P.5: Prefer simple and direct code over clever optimizations

  • 翻译: 优先使用简单直接的代码而不是聪明的优化.
  • 原因: 简单的代码更容易理解和维护.

P.6: Do not optimize prematurely

  • 翻译: 不要过早优化.
  • 原因: 过早优化可能导致代码复杂化且难以维护, 只有在实际性能瓶颈明确时才进行优化. 但是也不要做明显的劣化.

P.7: Make interfaces precisely and strongly typed

  • 翻译: 使接口精确且强类型化.
  • 原因: 强类型的接口可以帮助捕获错误并提高代码的安全性.

P.8: Keep it simple

  • 翻译: 保持简单.
  • 原因: 简单的设计和实现更容易理解和维护, 减少了引入错误的可能性.

P.9: Design for correctness, efficiency, and maintainability

  • 翻译: 设计时考虑正确性, 效率和可维护性.
  • 原因: 良好的设计可以在保证正确性的前提下提高效率, 并简化未来的维护工作.

P.10: Use const when possible

  • 翻译: 尽可能使用const.
  • 原因: const可以帮助编译器优化代码, 并防止意外修改数据. 参考const vs constexpr

P.11: Use constexpr when possible

P.12: Use inline functions for small, frequently called functions

  • 翻译: 对于小而频繁调用的函数使用内联函数.
  • 原因: 内联函数可以减少函数调用的开销, 特别是在高频调用的情况下.

P.13: Use RAII (Resource Acquisition Is Initialization) for resource management

  • 翻译: 使用 RAII 进行资源管理.
  • 原因: RAII 可以确保资源的正确获取和释放, 减少忘记释放资源导致的问题.

P.14: Prefer value semantics over reference semantics when possible

  • 翻译: 尽可能优先使用值语义而不是引用语义.
  • 原因: 值语义可以减少对对象生命周期的管理需求, 并简化代码逻辑.

P.15: Minimize dependencies between modules

  • 翻译: 最小化模块之间的依赖关系.
  • 原因: 减少依赖可以提高模块的独立性和可测试性, 并降低耦合度.

P.16: Use namespaces to avoid name clashes

  • 翻译: 使用命名空间避免名称冲突.
  • 原因: 命名空间可以隔离不同模块的标识符, 防止名称冲突. 当一个项目逐渐变大之后, 用到的第三方库也会越来越多, 如果不用命名空间隔离, 那么很容易发生名称冲突(即一个函数名或者类名在多个模块中都被定义).

P.17: Avoid global variables

  • 翻译: 避免全局变量.
  • 原因: 全局变量容易引发竞态条件和数据竞争, 增加调试难度. 需要注意的是单例(Singleton)也是一个全局变量.

补充材料

Amdahl’s Law

Amdahl’s Law 是并行计算领域中用于预测通过增加处理器数量所能达到的加速比的一个公式. 它由计算机科学家 Gene Amdahl 在 1967 年提出, 主要用于评估并行计算系统的效率和性能提升极限.

Amdahl’s Law 表明, 程序的加速比受到其串行部分的限制, 即无论增加多少处理器或并行执行单元, 程序的最大加速比都受限于不能并行化的那部分工作.

S l a t e n c y ( s ) = 1 ( 1 − P ) + P s S_{latency}(s) = \frac{1}{(1 - P) + \frac{P}{s}} Slatency(s)=(1P)+sP1

其中 S l a t e n c y S_{latency} Slatency是加速比, P P P是可并行化的工作比例, 而 s s s是并行处理单元的数量(比如 CPU 核心数).

根据这个定律, 如果一个程序中有一定比例的任务必须按顺序执行(不可并行化), 那么即使剩余任务可以完全并行化, 随着并行处理单元数量的增加, 整体加速效果将逐渐接近某个极限值. 这是因为随着并行处理单元的增加, 那些无法被并行化的任务所占的比例相对于整个执行时间变得越来越大. 这个给我们的指导就是一定要抓住主要矛盾, 抓住耗时最大的地方进行优化.

举例介绍

假定一个程序员花了不小代价将一部分代码提高了 10 倍(s = 10), 这个很厉害了. 但是这部分代码之前在总的运行时长中占比仅为 1%(即 P = 0.01 P=0.01 P=0.01). 那么最终这个程序的加速比将接近 S l a t e n c y ( s ) = 1 ( 1 − 0.01 ) + 0.01 10 = 1 0.99 + 0.001 = ≈ 1.009 S_{latency}(s) = \frac{1}{(1 - 0.01) + \frac{0.01}{10}} = \frac{1}{0.99 + 0.001} = \approx 1.009 Slatency(s)=(10.01)+100.011=0.99+0.0011=≈1.009. 性能提升了 0.9%. 很明显这样做的价值不大. 原因就是他找错了优化方向, 抓住了个芝麻粒大小的点在疯狂输出.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

arong-xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值