一般C&x2B+;性能改进提示 有人能指点我一篇文章,或者写一些关于C++编程习惯的建议,这些习惯通常是有效的(没有真正的缺点),并提高性能?我不是指编程模式和算法复杂性——我需要一些小东西,比如如何定义函数、在循环中要做/要避免的事情、在堆栈上分配什么、在堆上分配什么等等
这不是让一个特定的软件更快,也不是如何创建一个干净的软件设计,而是编程习惯——如果你总是应用它们,你会让你的代码快一点而不是慢一点。一个好的起点是系列,还有那些从中成长出来的特殊C++书籍。 这是我过去提到的一个列表。除此之外,Google C++的性能提示也有相当大的价值。一般C&x2B+;性能改进提示 有人能指点我一篇文章,或者写一些关于C++编程习惯的建议,这些习惯通常是有效的(没有真正的缺点),并提高性能?我不是指编程模式和算法复杂性——我需要一些小东西,比如如何定义函数、在循环中要做/要避免的事情、在堆栈上分配什么、在堆上分配什么等等,c++,C++,这不是让一个特定的软件更快,也不是如何创建一个干净的软件设计,而是编程习惯——如果你总是应用它们,你会让你的代码快一点而不是慢一点。一个好的起点是系列,还有那些从中成长出来的特殊C++书籍。 这是我过去提到的一个列表。除此之外,Google C++的性能提示也有相当大的价值。 中有许多提示,并且都是沿着这条线。 这类技巧的一个简单示例:尽可能使用预增量(++i)而不是后增量(i++)。这对于迭代器尤其重要,因为后增量涉及复制迭代器。您的优化器可能能够撤销此操作,但编写preincrement并不
中有许多提示,并且都是沿着这条线。
这类技巧的一个简单示例:尽可能使用预增量(++i)而不是后增量(i++)。这对于迭代器尤其重要,因为后增量涉及复制迭代器。您的优化器可能能够撤销此操作,但编写preincrement并不是额外的工作,所以为什么要冒险呢?更喜欢使用preincrement 对于int/pointer等,没有区别。
但是对于类类型,标准的实现方式需要创建一个新对象 因此,我们更喜欢预增量。以防万一,以后会更改类型。
然后你就不需要修改代码来应付。我养成了习惯,更喜欢编写
++I
而不是I++
,这并不是说当I
是int
时它会带来任何性能提升,但是当I
是迭代器时情况就不同了,迭代器可能有一个复杂的实现
那么假设你来自C编程语言,放弃在函数开始时声明所有变量的习惯:在函数流中需要变量时声明变量,因为函数可能包含早期的return
语句,然后才有效地使用开始时初始化的一些变量
除此之外,另一个资源是赫伯·萨特(又是他)和亚历克赛·亚历山德雷斯库
还有Scott Meyers的高效C++的最新版本:
最后,我想提及Tony Albrecht的演讲:不是说它包含了你可以盲目遵循的经验法则,而是它是一本非常有趣的读物。如果我理解正确,你问的是关于避免过早悲观的问题,这是避免过早优化的一个很好的补充。根据我的经验,要避免的第一件事是尽可能不复制大型对象。这包括:
- 通过(常量)引用将对象传递给函数
- 只要可行,就通过(常量)引用返回对象
- 确保在需要时声明引用变量
最后这一点需要一些解释。我不能告诉你我已经看过多少次了:
class Foo
{
const BigObject & bar();
};
// ... somewhere in code ...
BigObject obj = foo.bar(); // OOPS! This creates a copy!
正确的方法是:
const BigOject &obj = foo.bar(); // does not create a copy
这些准则适用于比智能指针或内置类型更大的任何对象。另外,我强烈建议您花时间学习评测代码。一个好的分析工具将有助于捕获浪费的操作。我建议阅读Jon Bentley的第二章(“性能”)。它不是C++特定的,但是这些技术也可以应用在C或C++中。该网站仅包含本书的部分内容,我建议您阅读本书。尽可能避免对同一数据集进行多次迭代。对于优化技术来说,“”by通常是最好的参考之一,既简单,也肯定更高级。另一个巨大的优势是,可以在他的网站上免费阅读。(他的网站请参见他名字中的链接,pdf文件请参见文章标题中的链接)
编辑:还要记住,90%(或更多)的时间花费在10%(或更少)的代码中。所以,一般来说,优化代码实际上就是要找出瓶颈。更重要的是,现代编译器的优化效果要比大多数编码器好得多,尤其是微优化,如延迟变量初始化等。编译器通常非常擅长优化,因此要花时间编写稳定、可靠和简单的代码
我认为,至少在大多数情况下,更多地关注算法的选择而不是微观优化是值得的。这是一篇关于这个主题的好文章:使用函子(实现了操作符()
的类)而不是函数指针。编译器可以更轻松地内联前者。这就是为什么C++的std::sort
比C的qsort
性能更好的原因。提高这些技能的最佳方法是阅读书籍和文章,但我可以为您提供一些技巧:
- 1-按引用接受对象,按值接受原语或指针类型,但如果函数存储指向对象的引用或指针,则使用对象指针
- 2-不要使用宏声明常量->使用静态常量
- 3-如果您的类可能是子类,请始终实现虚拟析构函数
- 避免多重继承
- 在必要时使用虚拟现实,而不仅仅是为了好玩
- 仅当不想使用模板化集合类时才使用模板化集合类
模板!使用模板可以减少代码量,因为您可以拥有一个可以与许多数据类型重用的类或函数/方法
考虑以下几点:
#include <string>
using std::basic_string;
template <class T>
void CreateString(basic_string<T> s)
{
//...
}
#包括
使用std::basic_字符串;
模板
void CreateString(基本字符串)
{
//...
}
基本字符可以由char、wchar、unsigned char或u组成
// this is a better option
void some_function(const std::string &str);
// than this:
void some_function(std::string str);
// Not a good idea, a whole other temporary copy of the (potentially big) vector will be created.
int sum(std::vector<int> v)
{
// sum all values of v
return sum;
}
// Better, vector is passed by constant reference
int sum(const std::vector<int>& v)
{
// v is immutable ("read-only") in this context
// sum all values of v.
return sum;
}