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

使用字面常量时传递std::string是否该用引用?示例时间差异解析

std::string参数传递:字面常量与引用的性能疑问

测试代码

bool funcWithoutReference(const std::string Text)
{
    return Text == "Hello!";
}

bool funcWithReference(const std::string& Text)
{
    return Text == "Hello!";
}

int main()
{
    // Example 1: Average execution time: 13.652 sec
    for (int i = 0; i < 10000000; i++) {
        std::string text = "Hello";
        funcWithoutReference(text);
    }

    // Example 2: Average execution time: 7.283 sec
    for (int i = 0; i < 10000000; i++) {
        funcWithoutReference("Hello");
    }

    // Example 3: Average execution time: 7.249 sec
    for (int i = 0; i < 10000000; i++) {
        std::string text = "Hello";
        funcWithReference(text);
    }

    // Example 4: Average execution time: 7.292 sec
    for (int i = 0; i < 10000000; i++) {
        funcWithReference("Hello");
    }

    return 0;
}

问题解答

1. 示例1与示例2的执行时间差异原因

示例1中,每次循环先创建std::string text对象,再以传值方式传递给函数。传值参数会触发std::string的拷贝构造函数,需要为形参分配内存并复制原对象的所有数据——这一操作在1000万次循环累加后,带来了显著的性能开销,导致执行时间较长。

示例2中,直接传递字符串字面量"Hello"给传值函数时,C++会先构造临时std::string对象,但编译器会触发拷贝消除优化:跳过临时对象到形参的拷贝步骤,直接在函数形参的内存位置构造临时std::string。这就避免了额外的拷贝开销,仅保留临时对象的构造开销,因此执行时间大幅降低。

2. 示例2与示例3、4执行时间接近的原因

  • 示例3中,将已创建的std::string变量以const引用方式传递,仅会为形参创建引用绑定,不会触发任何拷贝操作,开销极小,主要耗时在循环本身和字符串比较。
  • 示例4中,将字面量传递给const引用时,编译器会构造临时std::string对象并将引用绑定到该临时对象上(临时对象的生命周期会被延长至引用的生命周期),核心开销是临时对象的构造,和示例2中的临时对象构造开销一致。
  • 示例2经过拷贝消除优化后,仅保留临时对象的构造开销,和示例3、4的核心耗时环节对齐,因此三者执行时间几乎一致。

关于拷贝的补充说明

并非只有传递变量时才会发生拷贝:

  • 传递具名对象(如示例1中的text变量)给传值参数时,一定会触发拷贝构造,产生拷贝开销;
  • 传递临时对象(如字面量构造的std::string)给传值参数时,编译器会通过拷贝消除优化避免拷贝,此时不会产生额外的拷贝开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:18:26