高效实现strcpy并移动目标指针到末尾的STM32场景优化问询
现有实现的性能问题
你当前的实现最大的冗余开销是对源字符串做了2次遍历:strcpy 拷贝过程中需要遍历一次源字符串直到遇到\0终止符,后续strlen计算长度又会再次遍历一次源字符串,两倍的遍历开销在高频调用场景下对STM32这类资源有限的嵌入式平台损耗非常明显。
最优优化方案
方案1:使用stpcpy标准库函数(推荐)
stpcpy 是C标准库中专门用于字符串拷贝的函数,完成拷贝后会直接返回目标字符串末尾的指针,仅需要1次遍历即可同时完成拷贝+指针偏移的需求,性能比原有实现提升接近1倍:
#include <string.h> // 注意源字符串参数加const修饰更规范 void write_obj(char ** s, const char * t) { *s = stpcpy(*s, t); }
如果你的嵌入式编译器不支持stpcpy,可以自行实现,逻辑非常简单:
char* my_stpcpy(char *dst, const char *src) { while ((*dst++ = *src++) != '\0'); return dst - 1; }
方案2:逐字符拷贝的性能表现
你提到的逐字符拷贝方案性能远优于你当前的实现,因为仅需要1次遍历,而且在STM32平台下,简单的逐字符循环经过-O2优化后效率非常高,还可以很方便的增加边界检查逻辑避免缓冲区溢出,适配嵌入式场景的安全要求:
// 自带边界检查的实现,buf_total_len为目标缓冲区总长度,used_len为已使用长度 int write_obj_safe(char ** s, const char * t, size_t buf_total_len, size_t * used_len) { char *dst = *s; const char *src = t; // 预留1字节存终止符 while (*src != '\0' && (*used_len + 1) < buf_total_len) { *dst++ = *src++; (*used_len)++; } *dst = '\0'; *s = dst; // 返回0表示完整拷贝,-1表示缓冲区不足发生截断 return *src == '\0' ? 0 : -1; }
方案3:已知源字符串长度时的极限优化
如果你的调用场景中很多源字符串是固定长度的常量,可以直接传入长度参数,完全省去遍历找终止符的开销,性能最优:
void write_obj_fixed(char ** s, const char * t, size_t len) { memcpy(*s, t, len); *s += len; **s = '\0'; }
STM32平台额外优化建议
如果需要极限性能且拷贝的字符串普遍较长(>32字节),可以先判断源和目标地址是否4字节对齐,对齐后做32位批量拷贝,比逐字节拷贝效率高2~3倍,普通短字符串场景下逐字符实现已经足够。
提示:你提供的测试代码存在未初始化指针的bug,
json_str_ptr没有指向json_str数组的首地址,实际运行会发生非法访问,测试前需要补充json_str_ptr = json_str;初始化逻辑。
内容的提问来源于stack exchange,提问作者Kamil
相关产品推荐
相关产品推荐

