如何缩短C语言文件读取与结构体存储程序的运行时间?
优化C语言图存储程序的运行效率
以下是针对你的程序的具体优化方案,从内存分配、IO操作到编译优化多维度降低耗时:
1. 避免频繁内存扩容,改用预分配或倍增策略
当前程序每次添加边时的小幅度扩容(从代码逻辑推测后续会触发频繁扩容),是耗时的核心原因之一:
- 预分配空间:先完整扫描一遍输入文件,统计每个节点
vp对应的边数,初始化时直接为每个节点分配足够大小的存储数组,彻底避免动态扩容操作。 - 倍增扩容:如果无法预扫描文件,每次扩容时将数组大小翻倍(比如从1→2→4→8…),把内存分配的次数从O(n)降到O(logn),大幅减少分配开销。
2. 合并内存分配,提升缓存效率
当前每个节点的node和waga是两个独立的动态数组,既增加malloc调用次数,又导致数据分散在内存中,降低缓存命中率:
- 定义一个包含目标数据的结构体,将两个数组合并:
typedef struct { int vk; int waga; } Edge; typedef struct { Edge *edges; int count; // 当前已存储的边数 int capacity; // 数组总容量 } przejscie_t; - 初始化时只需一次
malloc分配capacity大小的Edge数组,既减少内存调用,又让相关数据在连续内存块中,访问时缓存命中率更高。
3. 优化文件读取速度
文件IO通常是程序的性能瓶颈,替换低效的格式化读取方式:
- 用
fread将文件批量读入内存缓冲区,再手动解析缓冲区中的整数,比fscanf等格式化函数快得多。 - 实现自定义的快速整数解析函数,跳过标准库格式化IO的冗余逻辑。
4. 减少指针解引用开销
在czytaj这类频繁调用的函数中,多次解引用(*graf)[vp]会产生冗余的内存访问,可通过临时变量缓存:
void czytaj(przejscie_t **graf, int vp, int vk, int waga) { przejscie_t *curr = &(*graf)[vp]; curr->edges[curr->count].vk = vk; curr->edges[curr->count].waga = waga; curr->count++; }
5. 开启编译器优化
启用编译器的优化选项,让编译器自动完成循环展开、指令重排、冗余代码消除等优化:
- GCC/Clang编译时添加
-O2或-O3参数; - MSVC使用
/O2选项。
内容的提问来源于stack exchange,提问作者Michał Jagodzinski
相关产品推荐
相关产品推荐

