编码修养系列---提升性能必学篇


程序员尼克

1、重视性能,限制输出

  • C语言中,负责格式化输出的printf()函数的运算成本要远高于其他运算,因为涉及到字符串转化为数字,很麻烦的。同理,scanf()函数和sscanf()函数的运算成本也高
  • 如果说加法运算的成本为1,那么printf()函数的运算成本接近200.运行依次输出语句相当于执行200次加法运算。
  • 因此,减少输出可以明显的压缩程序运行时间。没啥特殊需求,就默认不输出,是最好的选择。

2、用简单形式改写运算表达式

2.1 运算成本

  • 从c语言编译器层面来看,各个运算的成本,越来越大:
  • 位运算、逻辑运算<加减法运算<乘法运算<除法运算<处理浮点数
  • 运算时应该尽可能选择成本较低的运算,这样会提高程序运行速度

3、需要高效处理大文件时应使用二进制文件

  • 用c语言处理文件时,一般选用ASCII格式的文件。ASCII文件移植性强。
  • 但是ASCII文件的读写速度低于二进制文件,而且所占空间更大
  • 因此,如果程序型嫩南瓜至关重要或需要节约存储空间,最好选用二进制文件而不是ASCII文件

4、了解并使用压缩/未压缩结构体优缺点

4.1 怎样选择?

  • 如果没有限制栈大小或栈足够大,或者并不需要很多信号处理变量,那么最好采用未压缩结构体。这种结构体占内存较多,但处理速度更快,程序更易理解

  • 如果栈大小受限或需要很多信号处理变量,最好使用压缩结构体----使用位域减少所占空间大小的结构体。这种结构体回减慢运行速度,消耗大量时间占内存小

  • 这两种结构体各有利弊,大家根据实际场景妥善选择

4.2 示例

  • 用于信号处理的未压缩结构体:
/*下面结构体至少需要17字节存储,这里假设就是17字节*/
struct Signal {
    
    
	char input_character;
	int error_check;
	....
	int parity_check;
	int carrier_check;
	int power_check;
};
Signal signals[100000];//数组大小约170kB
  • 要知道有的栈大小才64kB,也就是无法容纳该数组,那么怎么解决呢?
  1. 将数组声明为静态变量
static Signal signals[100000];
  • 这样也不好,可能会扰乱整个程序的流程
  • 第二个解决方案就是减小Signal大小
/*用于信号处理的压缩结构体*/
struct Signal {
    
    
	char input_character;
	int error_check:1;
	....
	int parity_check:1;
	int carrier_check:1;
	int power_check:1;
};
Signal signals[100000];//数组大小约170kB
  • 用位域定义负责i信号处理的各元素后,Signal总大小减少到2字节之内
  • 因此九四hi声明10000个信号处理所需数组,也只需要20kB,这就满足64KB的限制了。

5、根据运行环境选择编程语言

  • 当程序员知道选择与运行环境最吻合的语言,那么项目就成功了一半。
  • 优秀的程序员是会多种语言的,不同的场景能有不同的编程语言选择
  • 选择与程序运行环境相吻合的编程语言是不容质疑的选择。不要说,java是无敌的,一招鲜或许能吃遍天,那得多累啊!

6、根据情况选择手段

  • 指针可以大幅度提高程序性能,但擅长使指针的不一定是能者。能够从语言提供的各种工具中挑选最合适的,并指导如何充分利用该工具才最重要。

7、选择更优秀的数据结构

  • 内存廉价且足够大的情况下,没必要节约内存。因此,数组大小可以远超需要保存到数据大小。(大量数据不适合)
  • 不要干啥都用数组,除了数组之外还要结构体、共用体、枚举、用户自定义数据结构等
  • 数组、链表、树、队列、栈还是其他数据结构都有自己的优缺点,需要综合考虑并作出最优选择。
  • 灵活选择,才是最优解。

8、小结

  • 5,6,7没啥讲的,工作中都会优先考虑的。
  • 第一个限制输出可以提高程序运行时间,倒是惊艳我了。反正,没必要的输出,就不要用了吧,降低程序运行性能。

猜你喜欢

转载自blog.csdn.net/weixin_43722052/article/details/110954319