C 语言字符串函数实现与性能
更新时间:2026-08-26。本文是
languages/c/主题高手层的骨架文档(占位),完整展开将在后续批次补齐。
本文要回答的问题
strlen是 O(n),为什么实际快得离谱?strcat在循环里为什么是性能杀手?- 拼字符串用
sprintf还是手动拼接?差多少?
一、字符串函数的复杂度陷阱
| 函数 | 复杂度 | 性能陷阱 |
|---|---|---|
strlen | O(n) | 库实现已用 SIMD 加速 |
strcpy | O(n) | 无 SIMD 版本时慢 |
strcat | O(n) 每次 | 循环拼接 O(n²):每次都从头找结尾 |
strcmp | 最坏 O(n) | 通常提前退出 |
strchr/strstr | O(n)/O(n·m) | 长串查找考虑 Boyer-Moore |
经典反模式:for (...) { strcat(buf, s); } —— 每轮都重新扫描整个 buf,n 次拼接是 O(n²)。解法:记录结尾指针,直接续写。
二、strlen 为什么快
标准库 strlen 不是逐字节扫,而是按字(8/16 字节)对齐读取,再用位运算找 0 字节;glibc 还用了 SIMD 指令一次比对 16/32 字节。所以它"看起来 O(n),常数极小"。这也是 编译优化 与硬件向量化的现实体现。
三、字符串构建对比
| 方式 | 特点 |
|---|---|
strcat 循环 | 最慢(O(n²)),别用 |
手动 memcpy + 尾指针 | 快、可控 |
sprintf/snprintf | 灵活,但解析格式有开销 |
固定缓冲 + 一次 snprintf | 多数场景够用 |
构建大字符串的通用建议:先算/估总长度,一次分配,用尾指针 + memcpy 续写(可配合 内存池 思路)。
四、与入门层的衔接
- strlen/sizeof 的区别,见 strlen 与 sizeof。
- 字符串函数族用法,见 字符串函数。
- 字符串常见坑,见 字符串陷阱。
- 字符串字面量存储,见 字符串字面量。
一句话总结
字符串性能的账要算"总扫描量":strcat 循环是 O(n²) 大坑、尾指针续写是正解,strlen 这类库函数已被 SIMD 优化到极致,瓶颈通常不在它身上。
本文为骨架文档:核心结构已就位,示例代码与实测数据将在后续批次补齐。