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

如何优化C++ Randomclass序列化中vector的数据追加效率?

C++序列化中vector追加操作的优化方案

你的序列化代码里用insert向std::vector<uint8_t>追加数据,确实有不少优化空间,下面是几个实用的优化方向:

1. 预分配内存,减少vector扩容开销

std::vector默认扩容策略是每次翻倍,频繁扩容会触发内存重新分配和数据拷贝。提前计算好所需总字节数并调用reserve(),能一次性分配足够空间,避免这些额外开销。

计算总字节数时需要考虑:

  • 字符串/容器长度的LEB128编码最大长度(uint32_t最多需要5字节)
  • 字符串/容器本身的字节数

示例代码:

std::vector<uint8_t> Buf;
const size_t nameLen = Ramdom.getName().length();
const size_t contentLen = Ramdom.getContent().size();
// 预分配:name的LEB128编码(最多5字节) + name长度 + content的LEB128编码(最多5字节) + content大小
Buf.reserve(5 + nameLen + 5 + contentLen);

2. 直接写入数据,避免临时vector

当前EncodeU32返回临时vector,再通过insert拷贝到目标容器,多了一次内存分配和拷贝。可以修改EncodeU32,直接把编码后的字节写入目标vector:

void EncodeU32(uint32_t d, std::vector<uint8_t>& out)
{
    // unsigned LEB128 encoding
    do
    {
        auto x = d & 0b01111111;
        d >>= 7;
        if (d)
            x |= 0b10000000;
        out.push_back(x); // 直接写入目标容器,无临时对象
    } while (d);
}

调用时直接传入目标vector即可,无需临时变量:

EncodeU32(Ramdom.getName().length(), Buf);

3. 用append替代insert追加字节序列

对于字符串或连续字节序列,vector::append()比insert(Buf.end(), begin, end)更贴合场景,部分标准库实现会对append做针对性优化,代码也更简洁:

// 追加name内容
Buf.append(Ramdom.getName().data(), Ramdom.getName().size());
// 追加content内容
Buf.append(Ramdom.getContent().data(), Ramdom.getContent().size());

优化后的完整代码示例

void EncodeU32(uint32_t d, std::vector<uint8_t>& out)
{
    do
    {
        auto x = d & 0b01111111;
        d >>= 7;
        if (d)
            x |= 0b10000000;
        out.push_back(x);
    } while (d);
}

std::vector<uint8_t> Serialize(Ramdomclass &Ramdom)
{
    std::vector<uint8_t> Buf;
    const size_t nameLen = Ramdom.getName().length();
    const size_t contentLen = Ramdom.getContent().size();
    Buf.reserve(5 + nameLen + 5 + contentLen);

    // 序列化name
    EncodeU32(nameLen, Buf);
    Buf.append(Ramdom.getName().data(), nameLen);

    // 序列化content
    EncodeU32(contentLen, Buf);
    Buf.append(Ramdom.getContent().data(), contentLen);

    // 组装最终结果
    std::vector<uint8_t> Result;
    Result.reserve(1 + 5 + Buf.size()); // 1字节版本号 + 最多5字节Buf长度 + Buf实际长度
    Result.push_back(0x00U);
    EncodeU32(Buf.size(), Result);
    // 用移动迭代器避免最后一次拷贝(Buf后续不再使用)
    Result.insert(Result.end(), std::make_move_iterator(Buf.begin()), std::make_move_iterator(Buf.end()));

    return Result;
}

额外优化点

如果getContent()返回的是std::vector<uint8_t>,可以用std::move转移数据到Result,避免冗余拷贝,就像上面代码里的std::make_move_iterator用法一样。

内容的提问来源于stack exchange,提问作者Sebastian Orteho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:40:17