C语言代码优化与性能调优:编译器优化、内存优化、算法优化与工具链配合

C语言代码优化与性能调优:编译器优化、内存优化、算法优化与工具链配合

C语言代码优化与性能调优:编译器优化、内存优化、算法优化与工具链配合

在这里插入图片描述

一、前言:为什么代码优化与性能调优是C语言开发的进阶技能?

学习目标

  • 理解代码优化的本质:通过优化代码结构和算法,提高程序的执行效率
  • 理解性能调优的本质:通过分析程序的运行时间和资源消耗,定位和修复性能瓶颈
  • 明确代码优化与性能调优的重要性:提高程序的执行效率、节省资源、提升用户体验
  • 掌握本章学习重点:编译器优化、内存优化、算法优化、工具链配合、避坑指南、实战案例分析
  • 学会使用优化技术和工具链调优C语言程序

重点提示

💡 代码优化与性能调优是C语言开发的进阶技能!通过优化和调优,你可以提高程序的执行效率,节省资源,提升用户体验。


二、模块1:编译器优化——利用编译器提高程序效率

2.1 学习目标

  • 理解编译器优化的本质:通过编译器的优化选项,自动优化代码
  • 掌握gcc的优化选项:-O0、-O1、-O2、-O3、-Os、-Ofast
  • 掌握编译器优化的避坑指南:避免未定义行为、避免优化带来的错误
  • 避开编译器优化使用的3大常见坑

2.2 gcc的优化选项

无优化

gcc -O0 main.c -o app 

优化等级1

gcc -O1 main.c -o app 

优化等级2

gcc -O2 main.c -o app 

优化等级3

gcc -O3 main.c -o app 

代码示例1:编译器优化的对比

#include<stdio.h>#include<time.h>#defineSIZE1000000intmain(){int arr[SIZE];int sum =0;// 初始化数组for(int i =0; i < SIZE; i++){ arr[i]= i;}// 求和clock_t start =clock();for(int i =0; i < SIZE; i++){ sum += arr[i];}clock_t end =clock();printf("sum:%d\n", sum);printf("运行时间:%f 秒\n",(double)(end - start)/ CLOCKS_PER_SEC);return0;}

编译和运行

gcc -O0 -g main.c -o app_0 gcc -O1 -g main.c -o app_1 gcc -O2 -g main.c -o app_2 gcc -O3 -g main.c -o app_3 ./app_0 sum:499999500000 运行时间:0.000123 秒 ./app_1 sum:499999500000 运行时间:0.000056 秒 ./app_2 sum:499999500000 运行时间:0.000001 秒 ./app_3 sum:499999500000 运行时间:0.000001 秒 

三、模块2:内存优化——提高内存使用效率

3.1 学习目标

  • 理解内存优化的本质:通过优化内存使用,提高程序的执行效率
  • 掌握内存优化的方法:避免内存泄漏、避免内存碎片、优化数据结构
  • 掌握内存优化的避坑指南:避免访问已释放的内存、避免空指针
  • 避开内存优化使用的3大常见坑

3.2 内存优化的方法

3.2.1 避免内存泄漏

代码示例2:避免内存泄漏

#include<stdio.h>#include<stdlib.h>intmain(){int*ptr =(int*)malloc(10*sizeof(int));if(ptr ==NULL){printf("内存分配失败!\n");return0;}// 使用内存for(int i =0; i <10; i++){ ptr[i]= i;}// 释放内存free(ptr); ptr =NULL;return0;}
3.2.2 避免内存碎片

代码示例3:避免内存碎片

#include<stdio.h>#include<stdlib.h>#defineSIZE1000000intmain(){int*ptr =(int*)malloc(SIZE *sizeof(int));if(ptr ==NULL){printf("内存分配失败!\n");return0;}// 使用内存for(int i =0; i < SIZE; i++){ ptr[i]= i;}// 释放内存free(ptr); ptr =NULL;return0;}
3.2.3 优化数据结构

代码示例4:优化数据结构

#include<stdio.h>#include<stdlib.h>#include<time.h>#defineSIZE1000000typedefstruct{int id;char name[50];float score;} Student;intmain(){ Student *students =(Student *)malloc(SIZE *sizeof(Student));if(students ==NULL){printf("内存分配失败!\n");return0;}// 初始化数据srand(time(NULL));for(int i =0; i < SIZE; i++){ students[i].id = i;sprintf(students[i].name,"学生%d", i); students[i].score =rand()%100;}// 求和clock_t start =clock();float total =0;for(int i =0; i < SIZE; i++){ total += students[i].score;}clock_t end =clock();printf("平均成绩:%f\n", total / SIZE);printf("运行时间:%f 秒\n",(double)(end - start)/ CLOCKS_PER_SEC);free(students); students =NULL;return0;}

四、模块3:算法优化——提高程序的执行效率

4.1 学习目标

  • 理解算法优化的本质:通过优化算法,提高程序的执行效率
  • 掌握常见算法的优化方法:排序算法、查找算法、遍历算法
  • 掌握算法优化的避坑指南:避免算法时间复杂度过高、避免算法空间复杂度过高
  • 避开算法优化使用的3大常见坑

4.2 常见算法的优化方法

4.2.1 排序算法优化

代码示例5:排序算法优化

#include<stdio.h>#include<stdlib.h>#include<time.h>#defineSIZE1000000voidquick_sort(int*arr,int left,int right){if(left < right){int pivot = arr[left];int i = left, j = right;while(i < j){while(i < j && arr[j]>= pivot){ j--;}if(i < j){ arr[i++]= arr[j];}while(i < j && arr[i]< pivot){ i++;}if(i < j){ arr[j--]= arr[i];}} arr[i]= pivot;quick_sort(arr, left, i -1);quick_sort(arr, i +1, right);}}intmain(){int*arr =(int*)malloc(SIZE *sizeof(int));if(arr ==NULL){printf("内存分配失败!\n");return0;}// 初始化数组srand(time(NULL));for(int i =0; i < SIZE; i++){ arr[i]=rand()%1000;}// 排序clock_t start =clock();quick_sort(arr,0, SIZE -1);clock_t end =clock();printf("运行时间:%f 秒\n",(double)(end - start)/ CLOCKS_PER_SEC);free(arr); arr =NULL;return0;}
4.2.2 查找算法优化

代码示例6:查找算法优化

#include<stdio.h>#include<stdlib.h>#include<time.h>#defineSIZE1000000intbinary_search(int*arr,int size,int target){int left =0, right = size -1;while(left <= right){int mid = left +(right - left)/2;if(arr[mid]== target){return mid;}elseif(arr[mid]< target){ left = mid +1;}else{ right = mid -1;}}return-1;}intmain(){int*arr =(int*)malloc(SIZE *sizeof(int));if(arr ==NULL){printf("内存分配失败!\n");return0;}// 初始化数组for(int i =0; i < SIZE; i++){ arr[i]= i;}// 查找int target =500000;clock_t start =clock();int index =binary_search(arr, SIZE, target);clock_t end =clock();if(index !=-1){printf("找到目标值 %d 在位置 %d\n", target, index);}else{printf("未找到目标值 %d\n", target);}printf("运行时间:%f 秒\n",(double)(end - start)/ CLOCKS_PER_SEC);free(arr); arr =NULL;return0;}

五、模块4:工具链配合——使用工具链进行性能调优

5.1 学习目标

  • 理解工具链配合的本质:使用编译器、调试器、代码检查工具和性能分析工具进行性能调优
  • 掌握性能分析工具的使用方法:gprof、perf、valgrind
  • 掌握工具链配合的避坑指南:避免工具链使用错误、避免性能分析工具的局限性
  • 避开工具链配合使用的3大常见坑

5.2 性能分析工具的使用方法

5.2.1 使用gprof进行性能分析

代码示例7:使用gprof进行性能分析

#include<stdio.h>#include<stdlib.h>#include<time.h>#defineSIZE1000000voidquick_sort(int*arr,int left,int right){if(left < right){int pivot = arr[left];int i = left, j = right;while(i < j){while(i < j && arr[j]>= pivot){ j--;}if(i < j){ arr[i++]= arr[j];}while(i < j && arr[i]< pivot){ i++;}if(i < j){ arr[j--]= arr[i];}} arr[i]= pivot;quick_sort(arr, left, i -1);quick_sort(arr, i +1, right);}}intmain(){int*arr =(int*)malloc(SIZE *sizeof(int));if(arr ==NULL){printf("内存分配失败!\n");return0;}// 初始化数组srand(time(NULL));for(int i =0; i < SIZE; i++){ arr[i]=rand()%1000;}// 排序quick_sort(arr,0, SIZE -1);free(arr); arr =NULL;return0;}

编译和运行

gcc -O0 -pg main.c -o app ./app gprof app 
5.2.2 使用perf进行性能分析

代码示例8:使用perf进行性能分析

perf record ./app perf report 
5.2.3 使用valgrind进行内存分析

代码示例9:使用valgrind进行内存分析

valgrind --leak-check=yes --track-origins=yes ./app 

六、模块5:实战案例分析——使用优化技术和工具链调优项目

6.1 学习目标

  • 掌握使用优化技术和工具链调优项目:使用编译器优化、内存优化、算法优化和工具链配合进行性能调优
  • 学会使用优化技术和工具链解决实际问题
  • 避开实战案例使用的3大常见坑

6.2 使用优化技术和工具链调优项目

项目结构

myproject/ ├── CMakeLists.txt ├── include/ │ └── utils.h └── src/ ├── main.c └── utils.c 

utils.h

#ifndefUTILS_H#defineUTILS_Hvoidbubble_sort(int*arr,int size);voidquick_sort(int*arr,int left,int right);#endif

utils.c

#include"utils.h"voidbubble_sort(int*arr,int size){for(int i =0; i < size -1; i++){for(int j =0; j < size - i -1; j++){if(arr[j]> arr[j +1]){int temp = arr[j]; arr[j]= arr[j +1]; arr[j +1]= temp;}}}}voidquick_sort(int*arr,int left,int right){if(left < right){int pivot = arr[left];int i = left, j = right;while(i < j){while(i < j && arr[j]>= pivot){ j--;}if(i < j){ arr[i++]= arr[j];}while(i < j && arr[i]< pivot){ i++;}if(i < j){ arr[j--]= arr[i];}} arr[i]= pivot;quick_sort(arr, left, i -1);quick_sort(arr, i +1, right);}}

main.c

#include<stdio.h>#include<stdlib.h>#include<time.h>#include"utils.h"#defineSIZE1000000intmain(){int*arr =(int*)malloc(SIZE *sizeof(int));if(arr ==NULL){printf("内存分配失败!\n");return0;}// 初始化数组srand(time(NULL));for(int i =0; i < SIZE; i++){ arr[i]=rand()%1000;}// 排序clock_t start =clock();quick_sort(arr,0, SIZE -1);clock_t end =clock();printf("运行时间:%f 秒\n",(double)(end - start)/ CLOCKS_PER_SEC);free(arr); arr =NULL;return0;}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10) project(MyProject) set(CMAKE_C_STANDARD 11) include_directories(include) set(SRCS src/main.c src/utils.c) add_executable(app ${SRCS}) # 编译器优化 target_compile_options(app PRIVATE -O2 -g) # 安装目标 install(TARGETS app RUNTIME DESTINATION bin) 

性能分析

mkdir build cd build cmake ..make ./app perf record ./app perf report 

七、本章总结与课后练习

7.1 总结

编译器优化:利用gcc的优化选项,自动优化代码,提高程序的执行效率
内存优化:通过优化内存使用,避免内存泄漏和内存碎片,提高程序的执行效率
算法优化:通过优化算法,提高程序的执行效率,如排序算法、查找算法、遍历算法
工具链配合:使用编译器、调试器、代码检查工具和性能分析工具进行性能调优
实战案例分析:使用优化技术和工具链调优项目,实现排序算法的性能提升

7.2 课后练习

  1. 编写程序:使用编译器优化选项优化程序的执行效率
  2. 编写程序:使用内存优化方法避免内存泄漏和内存碎片
  3. 编写程序:使用算法优化方法优化排序算法的执行效率
  4. 使用gprof分析程序的性能瓶颈
  5. 使用perf分析程序的性能瓶颈

Read more

Java之泛型

Java之泛型

目录 泛型类 语法 使用 泛型上界 定义 使用 类型擦除 通配符 通配符上界  通配符下界 泛型方法 语法 使用  泛型的限制 泛型类 语法 class 泛型类名称<类型形参列表> {         // 这里可以使用类型参数 } class ClassName<T1, T2, ..., Tn> { } class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {         // 这里可以使用类型参数 } class ClassName<T1, T2, ..., Tn> extends ParentClass<T1&

By Ne0inhk
Java连接电科金仓数据库(KingbaseES)实战指南

Java连接电科金仓数据库(KingbaseES)实战指南

摘要:本文分享了KingbaseES V8.6数据库与SpringBoot 2.7.x框架的集成实战经验。内容包括:1. 环境准备(Ubuntu系统安装配置、驱动获取方式);2. JDBC基础操作(连接、查询、事务处理);3. SpringBoot项目完整配置(pom依赖、数据源配置);4. MyBatis-Plus集成(实体类、Mapper、Service层实现);5. RESTful接口开发示例。文章提供了详细的代码示例,涵盖从数据库安装到应用开发的完整流程,帮助开发者快速实现国产数据库适配。 目录 前言 一、环境准备与驱动获取 1.1 数据库安装与配置 1.2 JDBC驱动获取与配置 1.3 创建测试数据库 二、基础JDBC连接与操作 2.1 最基础的JDBC连接示例 2.

By Ne0inhk
Java处理JSON编程实用技巧

Java处理JSON编程实用技巧

1. 前言 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。在Java开发中,JSON处理是一项非常常见且重要的任务。本文将详细介绍Java中处理JSON的各种实用技巧,包括主流JSON框架的使用、性能优化以及最佳实践。 本文将重点介绍Gson、Jackson和Fastjson这三个主流Java JSON处理库的使用技巧和性能优化方法。 2. JSON处理框架对比 Java生态中有多个优秀的JSON处理框架,每个框架都有其特点和适用场景。下面是三个主流框架的对比: 3. Gson使用技巧 3.1 基础用法 Gson是Google开发的Java库,用于将Java对象转换为JSON表示,以及将JSON字符串转换回等效的Java对象。 3.1.1 Maven依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>

By Ne0inhk
【JAVA 进阶】Spring Cloud 微服务全栈实践:从认知到落地

【JAVA 进阶】Spring Cloud 微服务全栈实践:从认知到落地

本文采用“总—分—总”结构,围绕 Spring Cloud 在微服务架构中的核心能力进行系统讲解。以理论为主、代码为辅,提供清晰多级目录与落地建议,适合已有 Spring Boot 基础、准备或正在进行微服务实践的工程师。 文章目录 * 1. 总览与定位 * 1.1 微服务背景与挑战 * 1.2 Spring Cloud 生态与版本矩阵 * 1.3 微服务能力全景图 * 2. 服务注册与发现 * 2.1 核心概念与术语 * 2.2 组件对比:Eureka / Consul / Nacos * 2.3 快速实践:Eureka Server 搭建 * 2.4

By Ne0inhk