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

为何返回字符串字面量比返回静态std::string性能更优?

为什么返回字符串字面量的std::string比返回拷贝的static std::string更快?

问题背景

函数return_string通过返回字符串字面量构造std::string,而return_static_string返回预分配static std::string的拷贝。性能测试显示return_string运行速度明显快于return_static_string,以下是原因解释:

测试代码

#include <numeric>

static std::string return_string(int type)
{
    switch(type)
    {
    case 0:
        return "apple";
    case 1:
        return "orange";
    case 2:
        return "banana";
    }
    
    return {};
}

static void default_return_string(benchmark::State& state) {
    std::vector<int> v(10000);
    std::iota(v.rbegin(), v.rend(), 0);

  for (auto _ : state) {
   for (const auto &n : v) {
        auto ignore = return_string(n % 3);
        benchmark::DoNotOptimize(ignore);
    }
  }
}
BENCHMARK(default_return_string);

static std::string return_static_string(int type)
{
  static const std::string ap = "apple";
  static const std::string ora = "orange";
  static const std::string ba = "banana";

    switch(type)
    {
    case 0:
        return ap;
    case 1:
        return ora;
    case 2:
        return ba;
    }
    
    return {};
}

static void static_return_string(benchmark::State& state) {
    std::vector<int> v(10000);
    std::iota(v.rbegin(), v.rend(), 0);

  for (auto _ : state) {
   for (const auto &n : v) {
        auto ignore = return_static_string(n % 3);
        benchmark::DoNotOptimize(ignore);        
    }
  }
}
BENCHMARK(static_return_string);

核心原因

  1. 字符串字面量返回的优化:返回字符串字面量时,编译器会触发返回值优化(RVO),C++17及以后更是强制实施复制消除——直接在调用方栈上构造std::string,无额外内存分配或拷贝。同时,测试中的字符串长度都在**小字符串优化(SSO)**范围内(通常15/22字节,依实现而定),完全不需要堆内存,构造销毁开销极低。

  2. static字符串拷贝的开销:return_static_string每次返回的是static std::string的拷贝,即便static对象仅初始化一次,每次返回都要执行std::string的拷贝构造。虽然SSO下是栈上复制,但仍需复制字符串内容、管理对象内部状态,比直接构造SSO字符串多了一次拷贝操作的开销。

优化方案:返回引用

改为返回const std::string&后,return_static_ref_string性能会反超return_string——此时无需任何拷贝或构造,仅返回已初始化static对象的引用,开销几乎为0。

优化后代码:

static const std::string& return_static_ref_string(int type)
{
  static const std::string ap = "apple";
  static const std::string ora = "orange";
  static const std::string ba = "banana";

    switch(type)
    {
    case 0:
        return ap;
    case 1:
        return ora;
    case 2:
        return ba;
    }
    
    return {};
}

static void static_return_ref_string(benchmark::State& state) {
    std::vector<int> v(10000);
    std::iota(v.rbegin(), v.rend(), 0);

  for (auto _ : state) {
   for (const auto &n : v) {
        const auto& ignore = return_static_ref_string(n % 3);
        benchmark::DoNotOptimize(ignore);        
    }
  }
}
BENCHMARK(static_return_ref_string);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:25:24