C++ C++;在for循环中使用预先计算的限制器

C++ C++;在for循环中使用预先计算的限制器,c++,C++,在像PHP这样的脚本语言中,使用这样的for循环是一个非常糟糕的主意: string s("ABCDEFG"); int i; for( i = 0; i < s.length(); i ++ ) { cout << s[ i ]; } 字符串s(“ABCDEFG”); int i; 对于(i=0;i

在像PHP这样的脚本语言中,使用这样的for循环是一个非常糟糕的主意:

string s("ABCDEFG");
int i;
for( i = 0; i < s.length(); i ++ )
{
   cout << s[ i ];
}
字符串s(“ABCDEFG”);
int i;
对于(i=0;icout如果优化器能够确定调用的
length
值不会改变,那么它可能确实能够优化调用,但是,如果您预先计算它,您是安全的(然而,在许多情况下,优化是不可能的,因为编译器不清楚条件变量是否可以在循环期间更改)

在许多情况下,这并不重要,因为所讨论的循环与性能无关。使用经典的
for(int i=0;i
for(int i=0,end=dominated();i
更容易输入和阅读

<>请注意,C++编译器通常会内嵌小函数,如<代码>长度>代码(通常会从字符串对象中检索预先计算的长度)。解释脚本语言通常需要一个函数调用的字典查找,因此对于C++,每个循环迭代一次冗余检查的相对超额可能要小得多。

  • 大概
  • 为了可读性
  • 有时。这取决于它在检测循环内长度不会改变方面有多好

  • 由于这是一种非常常见的情况,大多数编译器都会预先计算值,特别是在数组和非常常见的类型之间循环时,字符串可能是其中之一

    此外,引入一个附加变量可能会破坏其他一些循环优化—这实际上取决于您使用的编译器,并且可能会随着版本的不同而变化。
    因此,在某些情况下,“优化”可能适得其反

    如果代码不是真正的“热点”,性能的每一个滴答都很重要,那么您应该像以前那样编写代码:不需要“手动”预计算。


    编写代码时可读性也非常重要!
    优化应该非常小心,并且只有在深入分析之后才能进行!

    没错,
    s.length()
    通常会在每次循环迭代中进行评估。最好编写:

    size_t len = s.length();
    for (size_t i = 0; i < len; ++i) {
       ...
    }
    
    size\u t len=s.length();
    对于(尺寸i=0;i

    相反,对于一个只有几次迭代的循环,调用length()的频率并不重要。

    std::string.length()
    返回存储在容器中的固定变量。该变量已经预先计算过了

    只有当您知道字符串在循环中不会改变时,才能预先计算字符串的长度

    我不知道为什么在教程中会这样做。一些猜测:
    1) 使您养成习惯,以便在更改循环中字符串的值时不会被冲洗。
    2) 因为它更容易理解


    是的,优化器将尝试改进这一点,如果它能够确定字符串是否不会更改,这取决于
    字符串的实现方式

    对于以null结尾的字符串,您必须在每次迭代时计算大小

    std::string
    是一个容器,大小应在O(1)时间内返回,

    它(同样)取决于实现。

    简短回答,因为在某些情况下,您希望每次调用它


    其他人的解释:

    编译器可能能够保存调用的结果并优化掉所有额外的函数调用,但可能不行。然而,函数调用的成本将非常低,因为它所要做的就是返回一个int。除此之外,它很有可能是内联的,从而消除了fu的成本我会打电话给你的

    然而,如果你真的在意,你应该分析你的代码,看看预先计算值是否会使它更快。但是,选择预先计算值也不会有什么坏处。这不会花费你任何东西。不过,在大多数情况下,可能性是无所谓的。有些容器,比如list,其中size()可能不是O(1)操作,然后预计算将是一个非常好的主意,但对于大多数情况来说,这可能没有多大关系-特别是如果循环的内容足以压倒这样一个高效函数调用的成本,并且可能会被优化掉,但您必须进行测试才能确定-当然,您编译时的优化级别之类的事情可能会改变结果


    预先计算更安全,但通常不是必需的。

    在这种特殊情况下,
    std::string.length()
    通常是一个固定时间操作,通常效率很高

    对于一般情况,循环终止条件可以是任何表达式,而不仅仅是循环索引变量的比较(事实上,C/C++不识别任何特定索引,只识别初始值设定项表达式、循环测试表达式和循环计数器表达式(每次通过都执行)C/C++for循环基本上是复合语句的语法糖。

    它都是相对的

    PHP是被解释的,但是如果
    s.length
    进入PHP解释器的编译部分,它不会慢。但是即使它慢,在
    s[i]
    中花费的时间,以及在
    cout
    std::sting::length()中花费的时间呢
    返回一个预先计算的值。每次调用方法
    size()
    e、 g

    • std::list::size()
      重新计算大小和
    • std::vector::size()
      返回 预计算值
    这取决于如何实现容器的内部存储。
    std::vector
    是一个容量为2^n的数组,
    std::list
    是一个链接的li
    struct sdshdr {
        long len;
        long free;
        char buf[];
    }; 
    
    len + free
    
    std::string s("Rajendra");
    for (unsigned int i = 0; i < s.length(); i++)
    {
        std::cout << s[i] << std::endl;
    }
    
    size_type __CLR_OR_THIS_CALL length() const
        {   // return length of sequence
        return (_Mysize);
        }
    
    std::string s("Rajendra");
    int len = s.length();
    for (unsigned int i = 0; i < len; i++)
    {
        std::cout << s[i] << std::endl;
    }