优化入门

关于优化

我们应当忘记小的性能优化,百分之九十七的情况下,过早的优化都是万恶之源

这句话在很多时候都被引用到,以至于”不要优化”(注意,是”不要优化”而不是“不要过早优化”)已经深入人心,过度地推崇这条建议经常会成为如下行为的借口

  • 编程恶习
  • 逃避性能分析

还有另一个常识:优化是不重要的,这条常识的理由,在中也被提到过

程序员工具箱中最强大的优化技术就是不做优化

有几个理由支持这条禅式的忠告:其中一个是摩尔定律的指数效应——最聪明,最便宜,常常也是最迅速的性能提升方法,就是等上几个月,期待硬件性能更好

但是,时代是会变化的,如今,单个核心的性能增长非常慢,而且,如今的程序还必须运行在移动平台上(已经成为大多数),电池的电量和散热都制约了指令的执行效率,而优化,可以让程序永远保持活力

而且说性能无所谓的,只限于某些程序,对于工作负载很大以至于需要分布式处理的程序,性能影响就会非常大,以至于小小的优化都能节约莫大的成本,例如从1000台云主机将到只需600台

如何优化

1.使用更好的编译器,然后打开它们的优化选项

2.使用更好的算法,而不是英勇地去改进算法

3.使用更好的库

4.减少内存分配和复制,这是一个很有用的优化手段

5.使用更好的数据结构

6.提高并发行

如何测试性能

之前使用了gtest测试框架,觉得gtest的测试用例所使用的形式深的我心,于是仿照其形式写了一个测试运行时间的,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <queue>
#include <chrono>
using namespace std::chrono;

namespace _TimeTest
{
//A Base Timer
class TimerBase
{
public:
TimerBase() : m_start(system_clock::time_point::min()) {}

void Clear()
{
m_start = system_clock::time_point::min();
}

void Start()
{
m_start = system_clock::now();
}

bool IsStarted() const
{
return (m_start.time_since_epoch() != system_clock::duration(0));
}

unsigned long GetMs()
{
if (IsStarted())
{
system_clock::duration diff;
diff = system_clock::now() - m_start;
return (unsigned)(duration_cast<milliseconds>(diff).count());
}
return 0;
}
private:
system_clock::time_point m_start;
};

class TimeBaseTest
{
public:
virtual void run()=0;
virtual ~TimeBaseTest(){}
static TimerBase timer;
};

TimerBase TimeBaseTest::timer;
std::queue<TimeBaseTest *> tests;
}

#define TEST_CLASS(test_case_name) \
class TEST_CLASS_##test_case_name : public _TimeTest::TimeBaseTest {\
public:\
TEST_CLASS_##test_case_name()\
{\
_TimeTest::tests.push(this);\
}\
void run();\
};\

/* TEST_CLASS_INSTANCE
* 1.delcare the test class TEST_CLASS_test_case_name
* 2.get a instance of the class
* 3.define the run() for the class
* */

#define TEST_CLASS_INSTANCE(test_case_name) \
TEST_CLASS(test_case_name);\
auto test_case_name##_instance = new TEST_CLASS_##test_case_name;\
void TEST_CLASS_##test_case_name::run()

#define TimeTEST(test_case_name) TEST_CLASS_INSTANCE(test_case_name)

#define RunAllTimeTest(); \
while(!_TimeTest::tests.empty())\
{\
auto i = _TimeTest::tests.front();\
_TimeTest::tests.pop();\
std::cout << "\033[1;32:42m[ RUN ]\033[0m" << std::endl;\
i->timer.Start();\
i->run();\
std::cout << "\033[1;31:42m[ FINISH,USE TIME : "<< i->timer.GetMs() <<"ms]\033[0m\n" << std::endl;\
i->timer.Clear();\
delete i;\
}\

int main()
{
RunAllTimeTest();
return 0;
}

将上面的代码保存为TimeTest.h

然后使用的测试代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "TimeTest.h"

TimeTEST(test_1)
{
int a = 2;
std::cout << "this is test_1" << std::endl;
std::cout << a << std::endl;
}

TimeTEST(test_2)
{
std::cout << "this is test_2" << std::endl;
}

准备工作完成之后,让我们开始优化之旅