You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高效实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:27:00