P.9: Don't waste time or space(不要浪费时间和空间)

Reason(原因)

This is C++.

我们在用C++。

译者注:之所以选择C++而不是其他语言,就是希望使用最小的内存,获得更快的性能。没有道理不考虑时间和空间。

Note(注意)

Time and space that you spend well to achieve a goal (e.g., speed of development, resource safety, or simplification of testing) is not wasted. "Another benefit of striving for efficiency is that the process forces you to understand the problem in more depth." - Alex Stepanov

为达成目的而正确利用时间和空间(为了提高开发速度,资源安全,简化测试等)不是浪费。“努力提高效率的另一个好处是这个过程会促使你在更深层次上理解问题。”-亚历山大 斯特潘诺夫(STL之父)

Example, bad(反面示例)

struct X {    char ch;    int i;    string s;    char ch2;
    X& operator=(const X& a);    X(const X&);};
X waste(const char* p){    if (!p) throw Nullptr_error{};    int n = strlen(p);    auto buf = new char[n];    if (!buf) throw Allocation_error{};    for (int i = 0; i < n; ++i) buf[i] = p[i];    // ... manipulate buffer ...    X x;    x.ch = 'a';    x.s = string(n);    // give x.s space for *p    for (gsl::index i = 0; i < x.s.size(); ++i) x.s[i] = buf[i];  // copy buf into x.s    delete[] buf;    return x;}
void driver(){    X x = waste("Typical argument");    // ...}

Yes, this is a caricature, but we have seen every individual mistake in production code, and worse. Note that the layout of X guarantees that at least 6 bytes (and most likely more) are wasted. The spurious definition of copy operations disables move semantics so that the return operation is slow (please note that the Return Value Optimization, RVO, is not guaranteed here). The use of new and delete for buf is redundant; if we really needed a local string, we should use a local string. There are several more performance bugs and gratuitous complication.

是的,这个例子有点夸张,但是我在产品级代码中看到过所有特别的错误,甚至更糟。注意X的内存结构中至少有6个字节(很有可能更多)是多余的。这个关于copy操作的假想定义禁止了移动语法,因此返回操作会慢(请注意这里没有保证RVO,即返回值优化)。buffer的new和delete操作是多余的;如果确实需要局部字符串,我们应该使用局部的string对象。这里还有几个性能方面的问题和无谓的并发症。

译者注:返回值优化(RVO)的目的在于函数在返回对象时减少必要的拷贝和构造动作,具体可以参照一下连接:

https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/RVO_V_S_std_move?lang=en

Example, bad(反面示例)

void lower(zstring s){    for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]);}

This is actually an example from production code. We can see that in our condition we have i < strlen(s). This expression will be evaluated on every iteration of the loop, which means that strlen must walk through string every loop to discover its length. While the string contents are changing, it's assumed that toLower will not affect the length of the string, so it's better to cache the length outside the loop and not incur that cost each iteration.

这是一段来源于产品代码的实际的例子。我们可以看到i<strlen(s)的循环条件。这个表达式会在每次循环迭代时被计算,这意味着strlen必须每次迭代都遍历一次字符串以获取长度。当字符串的内容被修改时,我们可以认为toLower操作不会影响字符串长度,因此较好的做法是在循环外缓存字符串的长度而不必每次迭代都付出那么大的代码。

Note(注意)

An individual example of waste is rarely significant, and where it is significant, it is typically easily eliminated by an expert. However, waste spread liberally across a code base can easily be significant and experts are not always as available as we would like. The aim of this rule (and the more specific rules that support it) is to eliminate most waste related to the use of C++ before it happens. After that, we can look at waste related to algorithms and requirements, but that is beyond the scope of these guidelines.

关于浪费的单独的例子很少会造成显著影响,即使造成显著影响,通常也会很容易地被专家程序员排除。然而浪费会很容易地通过代码传播并显著化,而且专家程序员也不是只要我们需要就能有的。这个规则(和支持它的更具体的规则)的目的是在发生之前排除和C++用法相关的大部分浪费。

Enforcement(实施建议)

Many more specific rules aim at the overall goals of simplicity and elimination of gratuitous waste.

很多更具体的规则的总目标是简单性和无谓浪费的排除。

  • Flag an unused return value from a user-defined non-defaulted postfix operator++ or operator-- function. Prefer using the prefix form instead. (Note: "User-defined non-defaulted" is intended to reduce noise. Review this enforcement if it's still too noisy in practice.)

识别用户定义的非缺省后缀++操作符或者--操作符函数中的无用的返回值。推荐使用prefix格式。(注意:“用户定义的非缺省”目的是为排除干扰。如果在实践中仍然存在太多干扰,重新考虑本建议)

觉得本文有帮助,欢迎点赞并分享给更多的朋友!

更新文章,请关注微信公众号【面向对象思考】

C++核心准则边译边学-P.9 不要浪费时间和空间相关推荐

  1. C++核心准则边译边学-目标之外

    In.not: Non-aims(目标之外) The rules are not intended to be minimal or orthogonal. In particular, genera ...

  2. C++核心准则边译边学-I.7 说明后置条件

    I.7: State postconditions (说明后置条件) Reason(原因) To detect misunderstandings about the result and possi ...

  3. C++核心准则边译边学-P.12: 酌情使用支持工具

    P.12: Use supporting tools as appropriate(酌情使用支持工具) Reason(原因) There are many things that are done b ...

  4. C++核心准则边译边学-I.6 表达前提条件最好使用Expects()

    I.6: Prefer Expects() for expressing preconditions 表达前提条件最好使用Expects() Reason(原因) To make it clear t ...

  5. C++核心准则边译边学-I.27 考虑使用指向实现的指针技术获得稳定的ABI

    I.27: For stable library ABI, consider the Pimpl idiom(考虑使用指向实现的指针技术获得稳定的ABI) Reason(原因) Because pri ...

  6. C++核心准则边译边学-I.8 表示后置条件最好使用Ensures()

    I.8: Prefer Ensures() for expressing postconditions(表示后置条件最好使用Ensures()) Reason(原因) To make it clear ...

  7. modbus软件开发实战指南_C++核心准则?GSL:指南支持库

    GSL: Guidelines support library GSL:指南支持库 The GSL is a small library of facilities designed to suppo ...

  8. php 语法 条件变量,C ++核心准则:注意条件变量的陷阱

    今天,我写了一篇关于条件变量的恐怖文章.您应该意识到条件变量的这一问题.C ++核心准则CP 42仅声明:"不要无条件等待". 等待!条件变量支持一个非常简单的概念.一个线程准备一 ...

  9. 开源压缩算法brotli_Google的Brotli压缩算法,C ++核心准则以及更多新闻

    开源压缩算法brotli 在本周的开源新闻综述中,我们将介绍Google的Brotli压缩算法,适用于GitHub的Classroom,C ++ Core Guidelines等! 2015年9月20 ...

最新文章

  1. 2018-8-22-粒子滤波
  2. Linux系统查看分区文件系统类型
  3. crontab 用法
  4. 最短路径(Dijkstra、Bellman-Ford和SPFA算法)
  5. python标准模块os
  6. Linux下面护眼软件汇总
  7. 怎么转化大小写_亚马逊search term被限制,Search Terms只能写一行怎么办?
  8. [渝粤教育] 中国地质大学 金融保险业会计 复习题 (2)
  9. 题解 P2598 【[ZJOI2009]狼和羊的故事】
  10. C++工作笔记-简单工厂模式基础(用静态类传入函数指针,再进行调用)(仿大佬代码)
  11. [React] 尚硅谷 -- 学习笔记(一)
  12. 为什么真正的神经元学得更快
  13. mysql读出来的日期后面多了个 .0处理及layui中日期控件点击一闪而过处理
  14. 忆芯科技发布新一代国产主控芯片STAR1000P!4月完成量产版本
  15. 请问,非计算机专业,只为软考中级,哪一种最容易过?
  16. windows下docker 挂载数据卷报错 Error response from daemon: user declined directory sharing
  17. 图像处理学习——色彩空间
  18. 常用的7个计算机网络命令
  19. 一款消消乐游戏的自动解法
  20. 2021湖南省地区高考成绩排名查询,湖南高考排名查询方法,2021年湖南高考成绩位次全省排名查询...

热门文章

  1. The environmenthvariable 'Path' seems to ave some paths containing characters (';', '' or ';;').
  2. http报头之通用报头,请求报头,响应报头和实体报头
  3. php 横线,文字下面加横线怎么弄
  4. 计算机中的无线网卡使用哪两种类型的扩展槽,第三章计算机每一种扩展槽的相关信息.ppt...
  5. Android中蓝牙模块的使用
  6. /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found问题解决方法
  7. 40本编程开发电子书免费送
  8. excel 将图片的链接URL 显示为图片 转
  9. Win10 任务栏使用小图标
  10. 微信小程序之swiper轮播图