理解 C++/优化
|
现代的 编译器 通常具有设置以在编译过程中自动执行最常见的优化,这通常大大减少了程序员可能需要考虑的优化数量。现代编译器通常利用对特定 系统 和 架构 的了解,以及多年的优化研究成果,以进一步提高性能和最小化资源使用。这种优化最好留给编译器,因为手动操作可能会导致膨胀或性能成本。
当你遇到一个问题时,你会尝试找到解决问题的方案。有时解决方案很简单,而有时可能的解决方案并不那么简单,可能需要规划并决定采取哪些步骤。算法 是程序员用来解决问题的详细步骤。算法研究不断寻找更简单、更快速的方法来解决问题,重新考虑和减少问题,并将问题分解为更易于管理的问题。优化在算法编程中非常重要,但并非所有 算法 都能从优化中获益。
诸如在列表中搜索名称或对名称进行排序等问题可以通过算法解决。例如,排序算法从 1950 年代开始开发,新的解决方案仍在不断被发现。使用哪种算法的选择取决于时间或空间哪个更重要。如果程序速度比节省内存使用更重要,通常可以在预先存储一些值,以减少后续的计算量。同样,如果给定时间重新计算所有值,算法可以节省大量空间。
通常,一个程序可以通过简单地意识到它做了太多事情来优化。由于解决问题的方法有很多,一种解决方案可能有效,但与其他方法相比效率极低,就像第一个 排序算法,即 冒泡排序 一样。如果使用朴素方法,涉及搜索列表或 二叉树 的问题可能比实际需要的速度慢很多倍。如果程序的一部分执行速度太慢而无法可靠地执行,研究手头的問題以寻找更快的方法可能值得尝试。
冗余会增加解决问题所需的大小和时间。现代编译器通常可以消除一些冗余,例如从未使用过的变量、函数、值和语句,以及常量变量、值和计算结果。但是,算法的复杂性会降低编译器优化过程消除冗余的有效性。
- 冗余的示例
int foo = 0, bar = 2+2*4, baz = 9;
if (foo) {
while (foo) {
...
}
}
if (bar) {
do_loop(bar);
}
void do_loop(int bar) {
while (bar) {
...
}
return;
do_nothing();
}
程序员减少或消除冗余的常用策略
- 在创建小函数时假设有效状态。
- 将验证测试限制在不受你控制的事件中,例如用户输入、计算机资源和外部函数。
优化也反映在代码的有效性上。如果你可以使用一个已有的大量程序员可以访问的代码库/框架,你可以期望它更少错误,并针对你的特定需求进行了优化。
其中一些代码库以库的形式提供给 C++ 程序员。请务必考虑依赖项并检查实现方式:如果在没有考虑的情况下使用,这也可能导致代码膨胀和内存占用增加,以及降低代码的可移植性。我们将在本书的标准库部分仔细研究其中的一些库。