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

网友投稿 275 2022-09-19

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

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)的目的在于函数在返回对象时减少必要的拷贝和构造动作,具体可以参照一下连接:

​​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

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格式。(注意:“用户定义的非缺省”目的是为排除干扰。如果在实践中仍然存在太多干扰,重新考虑本建议)

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C++核心准则边译边学-实施建议
下一篇:C++核心准则T.120:只在确实有需要时使用模板元编程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~