两天的代码整洁之道培训,收获还算可以。主要树立良好的编程习惯,我想总结为几点:
1.函数编写。函数作为程序最重要的组成单元,编写短小精悍的功能函数是极其重要的;
2.复杂表达式、循环的编码。要避免复杂表达式,同时一个循环只做一件事,拆分循环并不影响性能;
3.复杂度度量。衡量函数的复杂度,可以使用圈复杂度来度量。
4.查询函数与修改函数的分离。
复杂度度量
- 代码行数
- 函数参数个数
- 调用其他函数、对象、包的数量
- 每行运算符的数量
- 调转语句个数(goto、break、continue、throw)
- 控制结构中的嵌套层数
- 变量个数(临时变量、全局变量)
- 同一变量的先后引用之间的代码行数(跨度)
- 变量生存的代码行数
圈复杂度
计算方法
- 1:从1开始,一直往下通过程序;
- 2:一旦遇到以下关键字,加1(if、else if、while、for、and、or);
- 3:给case语句中的每一种情况加1;
- 4:三元运算符a?b:c加1;
- 5:给catch语句加1
圈复杂度与维护表
圈复杂度 | 修改不成功率 |
---|---|
<10 | 5% |
20-30 | 20% |
50 | 40% |
圈复杂度 | 评价程度 |
---|---|
1-4 | low |
5-7 | middle |
8-10 | high |
11-15 | very high |
函数
创建理由
- 可维护性
- 职责单一
引入中间的,易懂的抽象
把一段代码放入一个命名恰当的函数内,是说明这段代码的最好的方法之一。
避免代码重复
- 简化复杂的布尔判断
- 隐藏全局变量、类成员变量
与直接对其修改相比,当需求变化是,可以修改函数体,而无需修改程序各处的调用.
查询函数和修改函数分离
10个1原则
- 每个变量只用于单一用途
- 每行代码只表达一件事
- 一个循环只做一件事
- 单一抽象层次原则
- 代码组织得一次只做一件事情
- 一种变化的仅仅修改一处
- 函数遵守单一职责
- 函数圈复杂度小于10
- 函数第一原则必须要短小
- 编写函数一心一意,心怀敬畏
函数最小行数的关键思想
度量方法是最小化人们理解它所需要的时间.
测试
循环拆分性能对比
#include<stdlib.h>
#include<iostream>
#include<stdio.h>
#include<ctime>
#include<Windows.h>
#include <Mmsystem.h>
using namespace std;
void foo()
{
}
void f_a()
{
long a= 0;
a = a+1;
a = 7/2;
}
void f_b()
{
long a= 0;
a = a+1;
a = 7/2;
}
void foo1()
{
long i;
for (i=0;i<100000000;i++)
{
f_a();
}
}
void foo2()
{
long i;
for (i=0;i<100000000;i++)
{
f_b();
}
}
void foo3()
{
long i;
for (i=0;i<100000000;i++)
{
f_a();
f_b();
}
}
void test1()
{
time_t start,stop;
start = time(NULL);
foo();//dosomething
stop = time(NULL);
printf("Use Time:%ld\n",(stop-start));
}
void test2()
{
double dur;
clock_t start,end;
start = clock();
foo();//dosomething
end = clock();
dur = (double)(end - start);
printf("Use Time:%f\n",(dur/CLOCKS_PER_SEC));
}
void test4()
{
LARGE_INTEGER t1,t2,tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
foo();//dosomething
QueryPerformanceCounter(&t2);
printf("Use Time:%f\n",(t2.QuadPart - t1.QuadPart)*1.0/tc.QuadPart);
}
void test5()
{
DWORD t1,t2;
t1 = GetTickCount();
foo();//dosomething
t2 = GetTickCount();
printf("Use Time:%f\n",(t2-t1)*1.0/1000);
}
void test6()
{
DWORD t1,t2,t3;
t1 = GetTickCount();
foo3();
t2 = GetTickCount();
foo1();//dosomething
foo2();//dosomething
t3 = GetTickCount();
printf("Use Time:%f\n",(t2-t1)*1.0/1000);
printf("Use Time:%f\n",(t3-t2)*1.0/1000);
printf("lasp Time:%ld\n",t3-t2-t2+t1);
}
int main()
{
//test1();
//test2();
//test4();
//test5();
test6(); //
return 0;
}
性能测试结果显示: 相差31ms. 约6%,可以忽略不计。这表明循环拆分并不影响性能。可以遵守一个循环只做一件事的要求。
总结
通过本次培训,我认识到编写整洁、简单代码的重要性,这使我更加坚持今后的编码工作要以此为准则,并向其他团队成员普及。