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

如何优化基于多分隔符的C++字符串分割函数性能?

优化按多分隔符分割字符串的C++实现

原代码的核心性能瓶颈

你的实现性能差主要源于几个关键问题:

  1. 频繁的临时字符串生成:每次调用str.substr(i, delimeters[j].size())都会创建新的临时字符串,伴随内存分配和拷贝,长字符串场景下开销极大。
  2. 冗余的字符串替换操作:判断分隔符是否非全空格时调用的replace函数,会完整复制分隔符并循环替换空格,属于完全不必要的性能浪费。
  3. 值传递参数:函数参数str和delimeters用值传递,每次调用都会触发完整拷贝,大字符串或多分隔符场景下这部分开销非常可观。
  4. 低效的匹配逻辑:逐个字符遍历+逐个分隔符匹配,没有优先匹配长分隔符的逻辑,既容易出现误匹配,又增加了不必要的循环次数。

优化后的实现

下面是针对上述问题优化后的代码,性能提升显著:

#include <vector>
#include <string>
#include <algorithm>
#include <cctype>

// 判断字符串是否全为空格
bool is_all_space(const std::string& s) {
    for (unsigned char c : s) {
        if (!std::isspace(c)) {
            return false;
        }
    }
    return true;
}

std::vector<std::string> split_with_delimeter(const std::string& str, const std::vector<std::string>& delimeters) {
    std::vector<std::string> result;
    // 预分配空间,减少vector动态扩容的开销
    result.reserve(str.size() / 8);

    std::string token;
    size_t pos = 0;
    const size_t str_len = str.size();

    // 预处理分隔符:按长度从长到短排序,优先匹配长分隔符,避免误匹配
    std::vector<std::string> sorted_delims = delimeters;
    std::sort(sorted_delims.begin(), sorted_delims.end(),
              [](const std::string& a, const std::string& b) {
                  return a.size() > b.size();
              });

    while (pos < str_len) {
        bool found_delim = false;
        for (const auto& delim : sorted_delims) {
            const size_t delim_len = delim.size();
            // 剩余长度不足,直接跳过当前分隔符
            if (pos + delim_len > str_len) {
                continue;
            }
            // 直接对比字符,避免生成临时子串
            bool match = true;
            for (size_t k = 0; k < delim_len; ++k) {
                if (str[pos + k] != delim[k]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                // 加入之前的有效token(非空)
                if (!token.empty()) {
                    result.push_back(std::move(token)); // 移动语义,避免字符串拷贝
                    token.clear();
                }
                // 非全空格的分隔符才加入结果
                if (!is_all_space(delim)) {
                    result.push_back(delim);
                }
                pos += delim_len;
                found_delim = true;
                break;
            }
        }
        if (!found_delim) {
            token += str[pos];
            ++pos;
        }
    }
    // 处理最后剩余的token
    if (!token.empty()) {
        result.push_back(std::move(token));
    }
    return result;
}

关键优化点说明

  1. const引用传递参数:避免了原代码中参数拷贝的开销,直接使用传入的原对象。
  2. 分隔符排序预处理:按长度降序排列分隔符,优先匹配长分隔符,既避免了短分隔符先匹配导致的错误(比如同时有"ab"和"a"时,先匹配"ab"),又减少了匹配次数。
  3. 直接字符匹配:代替substr生成临时字符串,直接对比原字符串的字符,彻底消除了临时字符串的内存分配和拷贝开销,这是性能提升的核心。
  4. 替换冗余的replace函数:用is_all_space直接遍历字符判断分隔符是否全为空格,没有任何多余的字符串操作。
  5. 移动语义:使用std::move(token)将token的内容转移到vector中,避免了字符串拷贝,进一步降低开销。
  6. 预分配容器空间:通过reserve提前为结果vector分配足够的空间,减少动态扩容时的内存重新分配和元素拷贝。

额外优化建议

  • 如果你的分隔符都是单字符,可以进一步优化:把单字符分隔符存入std::unordered_set<char>,直接O(1)判断当前字符是否为分隔符,性能会更上一层楼。
  • 若使用C++17及以上版本,可以用std::string_view代替std::string传递参数和存储结果,彻底避免不必要的字符串拷贝。

内容的提问来源于stack exchange,提问作者Cheese Danish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:10:24