这几个编程小技巧,让你代码效率提高一个档次,拿走不谢

版权声明:虽然我很菜,但我在努力! https://blog.csdn.net/qq_39331713/article/details/82353563

一、基本运算优化:

1、在乘以2(或2的整数次幂)或除以2(或2的整数次幂)的时候尽量用位运算来替代。

如果乘上一个2的倍数数值,可以改用左移运算(Left Shift) 加速 300%

x = x * 2; 
x = x * 64; 
//改为: 
x = x << 1; // 2 = 2^1 
x = x << 6; // 64 = 2^6

2、尽量减少使用除法运算(可以适当转换为乘法,如条件判断时将if (a == b / c)替换为if (a * c == b)。除法运算需要更多的移位和转换操作,往往需要的时间是相应乘法的两倍)

3、多使用+=、-=、*=、/=等复合运算符,以加一为例,效率由高到低是(i++ 、 i += 1 、 i = i + 1)

二、if条件判断优化

在进入讨论之前,我们先思考下面这个例子:

一个班的数学成绩如下:74、76、78、94、97、68、77、65、54、89…,总共有50个数据。要求用程序将分数为优秀(>=80)、良好(>=70)、及格(>=60)、不及格(>=0)四个分数段。

for 所有学生分数
 if 分数 < 60
   归为不及格段
 else if 分数 < 70
   归为及格段
 else if 分数 < 80
   归为良好段
 else 
   归为优秀段

这个伪代码逻辑没有问题,但是就这个数据来看这段代码运行效率糟透了。由于这个班的数学成绩绝大多数是良好和优秀,而这个程序需要三次if判断才能将分数归为良好,三次if判断加上一个else才能将分数归为优秀,所以绝大多数前两个if判断是不必要的。我们将if判断语句的顺序变换下:

for 所有学生分数
 if 分数 >= 80
   归为优秀段
 else if 分数 >= 70
   归为良好段
 else if 分数 >= 60
   归为及格段
 else 
   归为不及格段

在这个伪代码中绝大多数分数都在前两个if语句中完成了分段。两者的时间效率相差巨大,实际运行也发现,前者是后者运行时间的两倍多。

三、for循环优化

1、for循环变量初始化

在c语言中,我们常常这样使用for语句:

for (int i = 0; i < strlen(s); i++)

这看起来似乎很完美,代码也很漂亮,让我们再看看另一种写法:

int len = strlen(s);
for (int i = 0, i < len; i++)

二者唯一的不同在于后者用len变量将字符串s的长度保存了,在条件判断时直接将i与len比较。第二种方法用一个额外变量len避免了每次条件判断都要重复执行函数strlen(s),而执行该函数是非常耗时的(假设字符串的长度为n,函数执行的复杂度为O(n)),尤其是当for循环体的语句比较少,字符串比较长的时候。在很多leetcode题目中,两种不同的写法需要的运行时间相差巨大。

同样在C++、Java中,这种写法for (int i = 0; i < s.length(); i++),也是不值得推荐的,尽管C++编译时期有的编译器会将length()函数用内联或者一个确定的变量来替代,Java也会将其用“属性”来替代,但我仍然倾向于使用后者。

有意思的是,在Python的语法中,for循环用这种方式来表示:

for i in range(len(s))

这就避免了重复去求字符串s的长度,这种方法既有语义感,又获得了高性能。

2、变量定义位置(for循环内部还是外部)

//内部
for (int i = 0; i < 10; i++)
{
 string s = ss[i];
 ...
}


//外部
string s;
for (int i = 0; i < 10; i++)
{
 s = ss[i];
 ...
}

如果定义在内部,每次循环都要重新定义string变量s,意味着每次循环都要调用构造和析构函数;而定义在外部每次循环只需要调用复制构造函数。一般建议将大的对象定义到外部,提高运行效率,把小的对象定义在里面,提高程序可读性。

总结:

当然,上述仅代表本人的看法,如有错误,不吝指教。

猜你喜欢

转载自blog.csdn.net/qq_39331713/article/details/82353563