使用字符串这种方式效率低下?

时间:2011-10-15 02:28:54

标签: c++

我是c ++的新手,我的老师在我的代码中使用字符串遇到了问题。虽然我很清楚我必须在课堂上停止这样做,但我很好奇为什么它是错的。在这个程序中,我分配的五个字符串将被重复使用不少于4到5次,因此我将文本放入字符串中。我被告知要停止这样做,因为效率低下。为什么?在c ++中,文本字符串应该被输入而不是存储到字符串中,如果是这样,为什么呢?下面是一些程序,请告诉我为什么它不好。

 string Bry = "berries";
 string Veg = "vegetables";
 string Flr = "flowers";
 string  AllStr;
 float Tmp1, Precip;
 int Tmp, FlrW, VegW, BryW, x, Selct;   
 bool Cont = true;
 AllStr = Flr + ", " +  Bry + ", " + "and " + Veg;

8 个答案:

答案 0 :(得分:9)

回答是否使用字符串是低效的,这在很大程度上取决于你如何使用它们

首先,我认为你应该使用C ++字符串作为默认值 - 如果您实际测量并发现C ++字符串太慢,则只会转到原始C字符串。优点(主要用于安全性)太大了 - 用原始C字符串搞砸缓冲区管理太容易了。所以我不同意你的老师说这过度效率不高。

也就是说,了解使用C ++字符串的性能影响非常重要。由于它们总是动态分配,因此最终可能会花费大量时间复制和重新分配缓冲区。 这通常不是问题;通常还有其他东西占用更多的时间。但是,如果您在循环中间执行此操作,这对程序的性能至关重要,则可能需要找到另一种方法。

简而言之,过早优化通常是一个坏主意。编写明显正确的代码,即使运行时间稍长。但要注意你在同一时间所做的成本和权衡;这样,如果事实证明C ++字符串实际上大大减慢了你的程序,你就会知道要修改什么来解决这个问题。

答案 1 :(得分:7)

是的,由于以下原因,效率相当低:

  • 构造std::string对象时,必须为字符串内容分配存储空间(可能是也可能不是单独的动态内存分配,具体取决于小字符串优化生效)并复制作为构造函数参数的文字字符串。例如,当你说:string Bry = "berries"它分配一个单独的内存块(可能来自动态内存),然后将“berries”复制到该块。
    • 因此,您可能需要额外的动态内存分配(花费时间),
    • 必须执行复制(花费更多时间),
    • 并以相同字符串的两个副本结束(成本空间)。
  • 使用std::string::operator+生成一个新的字符串,这是串联的结果。因此,当您连续编写多个+运算符时,您会有多个临时串联结果和大量不必要的复制。

对于您的示例,我建议:

  • 使用字符串文字,除非您确实需要std::string中仅提供的功能。
  • 使用std::stringstream将多个字符串连接在一起。

通常情况下,代码可读性优于此类微优化,但幸运的是,在这种情况下,您可以同时具备性能和可读性。

答案 2 :(得分:3)

你的老师是对是错。他/她是正确的,在运行时从子串中构建字符串比简单地在代码中提供完全预先构建的字符串开始时效率低 - 但他/她认为效率必然是担心的重要因素是错误的在这种情况下。

在很多情况下,效率根本无关紧要。完全没有。例如,如果上面的代码很少被执行(例如每秒不超过一次),那么测量“最有效版本”和不那么高效版本之间的差异几乎是不可能的。 。鉴于此,确定其他因素(如代码可读性和可维护性)比最大化效率更重要是完全合理的。

当然,如果您的程序将每秒重建这些字符串数千或数百万次,那么确保您的代码最高效,即使以牺牲可读性/可维护性为代价,也是一个很好的权衡。但我怀疑这就是这种情况。

答案 3 :(得分:2)

你的方法几乎是完美的 - 尝试只宣告一次。但如果它不被使用超过一次 - 不要浪费你的手指键入它:-)即10行程序

我建议的唯一变化是使字符串const能帮助编译器优化程序。

如果教练仍然不同意 - 请找一位新教练。

答案 4 :(得分:1)

效率低下。做最后一行的速度会快4-5倍。

至少你应该使用+ =

+ =表示您将避免使用+运算符创建新字符串。

教师知道当你执行string = string + string时C ++会创建一个立即销毁的新字符串。

答案 5 :(得分:1)

效率可能不是在学校作业中不使用字符串的好理由但是,如果我是一名教师并且主题不是关于某些非常高级别的应用程序,我不希望我的学生使用字符串。

真正的原因是字符串隐藏了低级内存管理。大学毕业的学生应具备基本的记忆管理技能。虽然现在在工作环境中,程序员大多数时间都不处理内存管理,但总有一些情况需要了解发生在幕后的情况,以便能够解决您遇到的问题。

答案 6 :(得分:0)

根据给定的上下文,看起来您应该能够将AllString声明为const或字符串文字,而不需要所有子字符串和添加。假设有更多内容,将它们声明为文字string对象在运行时分配内存。 (并且,并不是说这里有任何实际影响,但你应该知道stl容器对象有时会分配一个默认的最小空间,该空间大于最初的空间数量,作为预期稍后修改的优化的一部分我不确定std :: string是否在声明/赋值上执行此操作。)如果您只是将它们用作文字,则将它们声明为const char*或{{1内存和运行时性能都比较容易,你仍然可以在#define操作中将它们用作r值。如果您在代码中使用其他方式而不向我们展示,那么它是否需要被更改或操纵以确定它们是否需要string

如果您正在尝试学习编码,那么在实践中无关紧要的低效率仍然是您应该注意的事情,如果没有必要,请避免。在生产代码中,有时会有理由做这样的事情,但如果没有任何正当理由,那就太邋。了。她指出它是正确的,但她应该做的是将其作为谈论各种权衡的起点 - 记忆,速度,可读性,可维护性等。如果她是老师,她应该寻找“教学时刻“喜欢这样,而不仅仅是一个骂人的机会。”

答案 7 :(得分:-1)

你可以使用string.append(); 它比+或+ =

更好