【问题标题】:C++ string literals vs. const stringsC++ 字符串文字与 const 字符串
【发布时间】:2011-05-20 16:40:08
【问题描述】:

我知道 C/C++ 中的字符串文字具有静态存储持续时间,这意味着它们“永远”存在,即只要程序运行。

因此,如果我有一个函数被非常频繁地调用并使用这样的字符串文字:

void foo(int val)
{
    std::stringstream s;
    s << val;
    lbl->set_label("Value: " + s.str());
}

set_label 函数将const std::string&amp; 作为参数。

我应该在这里使用const std::string 代替字符串文字还是没有区别?

我需要尽可能减少运行时内存消耗。

编辑:

我的意思是将字符串文字与在某种常量头文件中初始化的const std::string prefix("Value: "); 进行比较。

此外,这里的连接返回一个临时值(我们称它为 Value: 42 并且对这个临时值的 const 引用被传递给函数 set_text(),我在这方面是否正确?

再次感谢您!

【问题讨论】:

  • 你的魔术 8 球怎么说?
  • 如果你想尽量减少运行时内存消耗,如何修改 set_label 采用 const char * 并使用 char * 代替字符串?
  • @user347594:很遗憾,我无法修改set_label
  • @Noah:拥有一个 const 字符串会大大提高代码的可维护性,但我会为了这个应用程序的内存优化而牺牲它,因此我的问题 =)
  • 既然你说这个函数被频繁调用,你可能不想使用stringstream,这很慢。见stackoverflow.com/questions/4351371/…

标签: c++ string constants literals


【解决方案1】:

您的程序每次都在相同的文字上运行。没有更有效的存储形式。将构造一个 std::string,在堆上复制,然后在每次函数运行时释放,这完全是浪费。

【讨论】:

  • 除非您知道 OP 使用的是什么实现,否则您无法知道这并不是正在发生的事情,也不知道编译器优化不会使您的陈述完全错误。
  • Noah 是对的,像这样的小字符串可能根本不使用堆存储。 stringstream 另一方面是很重量级的...
  • @Noah:我很确定无论编译器如何优化,它都想不出比文字字符串更有效的东西。
  • @DeadMG 使用字符串文字会比使用在常量头文件中定义的const std::string 更好还是没有区别?
  • @vic:真的没关系。字符串文字被静态分配一次,之后永远被引用。没有办法以更有效的方式存储这些数据,故事结束。
【解决方案2】:

你将如何构建你的 const std::string ?如果你从一些字符串字面量来做,最后它只会是 worse (或者如果编译器做得很好,则相同)。字符串文字不会消耗太多内存,而且静态内存也可能不是您所缺少的那种内存。

如果您可以从文件中读取所有字符串文字,并在不再使用字符串时将内存还给操作系统,则可能有一些方法可以减少内存占用(但它可能会减慢程序很多)。

但在做这种事情之前,可能还有很多其他方法可以减少内存消耗。

【讨论】:

    【解决方案3】:

    将它们存储在某种资源中并根据需要加载/卸载它们。

    【讨论】:

      【解决方案4】:

      这将使用更少的内存并运行得更快(如果您的编译器支持,请使用snprintf):

      void foo(int val)
      {
          char msg[32];
          lbl->set_label(std::string(msg, sprintf(msg, "Value: %d", val)));
      }
      

      如需更快的实现,请查看C++ performance challenge: integer to std::string conversion

      【讨论】:

      • +1 进行优化!回到我最初的问题,字符串文字会比使用常量头文件中定义的const std::string 更高效吗?
      • @vic:这真的取决于你是否需要长度。 std::string 缓存长度,因此读取变量是一件小事,而使用 char* 您必须使用 strlen 进行迭代。然而,字符串字面量本身是一个字符数组,它携带它的长度作为编译时类型信息的一部分,这是最快的(当编写代码以利用它时)。
      • 您在答案中漏掉了一个括号。无论如何+1。我喜欢这个解决方案。
      • @whoan:感谢您提请我注意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      相关资源
      最近更新 更多