跳到主要内容C 语言代码优化与性能调优:编译器优化、内存优化、算法优化与工具链配合 | 极客日志C算法
C 语言代码优化与性能调优:编译器优化、内存优化、算法优化与工具链配合
综述由AI生成系统讲解了 C 语言代码优化与性能调优的关键技术。内容包括编译器优化选项的使用、内存管理技巧(避免泄漏与碎片)、常见算法的效率提升以及 gprof、perf 等工具链的配合。通过实战项目演示了如何综合运用上述方法提高程序执行效率与资源利用率。
念念不忘38 浏览 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>
#define SIZE 1000000
int main() {
int arr[SIZE];
sum = ;
( i = ; i < SIZE; i++) {
arr[i] = i;
}
start = clock();
( i = ; i < SIZE; i++) {
sum += arr[i];
}
end = clock();
(, sum);
(, ()(end - start) / CLOCKS_PER_SEC);
;
}
int
0
for
int
0
clock_t
for
int
0
clock_t
printf
"sum:%d\n"
printf
"运行时间:%f 秒\n"
double
return
0
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 避免内存泄漏
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(10 * sizeof(int));
if (ptr == NULL) {
printf("内存分配失败!\n");
return 0;
}
for (int i = 0; i < 10; i++) {
ptr[i] = i;
}
free(ptr);
ptr = NULL;
return 0;
}
3.2.2 避免内存碎片
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000000
int main() {
int* ptr = (int*)malloc(SIZE * sizeof(int));
if (ptr == NULL) {
printf("内存分配失败!\n");
return 0;
}
for (int i = 0; i < SIZE; i++) {
ptr[i] = i;
}
free(ptr);
ptr = NULL;
return 0;
}
3.2.3 优化数据结构
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1000000
typedef struct {
int id;
char name[50];
float score;
} Student;
int main() {
Student* students = (Student*)malloc(SIZE * sizeof(Student));
if (students == NULL) {
printf("内存分配失败!\n");
return 0;
}
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;
return 0;
}
四、模块 3:算法优化——提高程序的执行效率
4.1 学习目标
- 理解算法优化的本质:通过优化算法,提高程序的执行效率
- 掌握常见算法的优化方法:排序算法、查找算法、遍历算法
- 掌握算法优化的避坑指南:避免算法时间复杂度过高、避免算法空间复杂度过高
- 避开算法优化使用的 3 大常见坑
4.2 常见算法的优化方法
4.2.1 排序算法优化
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1000000
void quick_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);
}
}
int main() {
int* arr = (int*)malloc(SIZE * sizeof(int));
if (arr == NULL) {
printf("内存分配失败!\n");
return 0;
}
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;
return 0;
}
4.2.2 查找算法优化
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1000000
int binary_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;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
int main() {
int* arr = (int*)malloc(SIZE * sizeof(int));
if (arr == NULL) {
printf("内存分配失败!\n");
return 0;
}
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;
return 0;
}
五、模块 4:工具链配合——使用工具链进行性能调优
5.1 学习目标
- 理解工具链配合的本质:使用编译器、调试器、代码检查工具和性能分析工具进行性能调优
- 掌握性能分析工具的使用方法:gprof、perf、valgrind
- 掌握工具链配合的避坑指南:避免工具链使用错误、避免性能分析工具的局限性
- 避开工具链配合使用的 3 大常见坑
5.2 性能分析工具的使用方法
5.2.1 使用 gprof 进行性能分析
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1000000
void quick_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);
}
}
int main() {
int* arr = (int*)malloc(SIZE * sizeof(int));
if (arr == NULL) {
printf("内存分配失败!\n");
return 0;
}
srand(time(NULL));
for (int i = 0; i < SIZE; i++) {
arr[i] = rand() % 1000;
}
quick_sort(arr, 0, SIZE - 1);
free(arr);
arr = NULL;
return 0;
}
gcc -O0 -pg main.c -o app
./app
gprof app
5.2.2 使用 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
#ifndef UTILS_H
#define UTILS_H
void bubble_sort(int* arr, int size);
void quick_sort(int* arr, int left, int right);
#endif
#include "utils.h"
void bubble_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;
}
}
}
}
void quick_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);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "utils.h"
#define SIZE 1000000
int main() {
int* arr = (int*)malloc(SIZE * sizeof(int));
if (arr == NULL) {
printf("内存分配失败!\n");
return 0;
}
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;
return 0;
}
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 课后练习
- 编写程序:使用编译器优化选项优化程序的执行效率
- 编写程序:使用内存优化方法避免内存泄漏和内存碎片
- 编写程序:使用算法优化方法优化排序算法的执行效率
- 使用 gprof 分析程序的性能瓶颈
- 使用 perf 分析程序的性能瓶颈
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online