C++ 在循环中运行的函数中声明变量的开销?

C++ 在循环中运行的函数中声明变量的开销?,c++,performance,variables,declaration,C++,Performance,Variables,Declaration,已经有人问过这个问题了。答案是“局部变量的堆栈空间通常分配在函数范围内。”因此,在循环外部/内部声明变量的开销没有区别 现在,假设我们有一个片段,其中循环中有一个函数: void do_sth(int &i) {int var=i+1;} int i = 0; while(i < 100) { do_sth(i); i++; } void do_sth(int&i){int var=i+1;} int i=0; 而(i

已经有人问过这个问题了。答案是“局部变量的堆栈空间通常分配在函数范围内。”因此,在循环外部/内部声明变量的开销没有区别

现在,假设我们有一个片段,其中循环中有一个函数:

void do_sth(int &i) {int var=i+1;}
int i = 0;
while(i < 100)
{
    do_sth(i);
    i++;
}
void do_sth(int&i){int var=i+1;}
int i=0;
而(i<100)
{
做某事(我);
i++;
}
以及第二个代码段,其中在外部声明了一个变量:

int i = 0;
int var;
while(i < 100)
{
    var = i+1;
    i++;
}
inti=0;
int-var;
而(i<100)
{
var=i+1;
i++;
}

我的问题是-在实际场景中(使用现代编译器)第一个代码段的开销是多少?如果确实存在开销,那么它有多大?它是否可以与在循环的每个步骤中对整数进行额外的加法(运算符+)相比?

任何合理的编译器,如果被要求在最基本的级别上优化代码,都会为这两个代码段生成完全相同的指令。

任何合理的编译器,如果被要求在最基本的级别上优化代码,将为两个代码段生成完全相同的指令。

启用优化的现代编译器很可能会内联函数调用,前提是它符合内联要求(无外部链接等),因此两个版本将生成相同的代码


如果函数没有内联,那么确实存在开销:函数调用和函数返回,参数在堆栈中传递。这不仅仅是一个简单的添加。

启用了优化的现代编译器很可能会内联函数调用,前提是它符合内联要求(无外部链接等),因此这两个版本将生成相同的代码


如果函数没有内联,那么确实存在开销:函数调用和函数返回,参数在堆栈中传递。这不仅仅是一个简单的添加。

当前的编译器足够聪明,可以检查变量和函数的使用情况,并在编译时和链接时优化代码。因此,经过优化后,这两段代码之间的差异应该可以忽略不计。此链接时优化文档应提供关于此问题的更好见解。

当前编译器足够聪明,可以检查变量和函数的使用情况,并在编译时和链接时优化代码。因此,经过优化后,这两段代码之间的差异应该可以忽略不计。此链接时间优化文档应提供有关此问题的更好见解。

int i=0;
int i = 0;
int var;
while(i < 100)
{
    var = i+1;
    i++;
}

int i = 0;
while(i < 100)
{
    int var = i+1;
    i++;
}
int-var; 而(i<100) { var=i+1; i++; } int i=0; 而(i<100) { int var=i+1; i++; }
通常会生成完全相同的代码。但是,使用第二种方法有很好的理由。
它的意图更加清晰,代码可能会被更好地理解,因为编译器知道var只在循环期间需要

inti=0;
int-var;
而(i<100)
{
var=i+1;
i++;
}
int i=0;
而(i<100)
{
int var=i+1;
i++;
}
通常会生成完全相同的代码。但是,使用第二种方法有很好的理由。

它的意图更清晰,代码可能会被更好地优化,因为编译器知道var只在循环期间需要

我假设编译器可以最大限度地优化代码(否则,谈论性能有点毫无意义)

如果编译示例中的循环时,
do\u sth
的主体可见,编译器很可能会将其内联,然后将
var
的赋值(以及
var
的堆栈空间分配)作为死代码删除,因此对于这种情况,开销实际上并不存在。如果
do\u sth
不能内联,那么函数调用的代价比int的声明更重要。如果函数可以内联,编译器很可能将第一个版本转换为第二个版本,即使
var
不是死代码。所以对于这样的例子,这真的不重要


如果您的变量是更复杂的类型(非POD类类型),这可能很重要。在这种情况下,第一个版本将为每个迭代调用一次构造函数和析构函数,而第二个版本将为每个迭代调用一次赋值运算符,并且只调用一次构造函数和析构函数。但是请注意,这并没有说明哪个版本更快(取决于这些方法的实现)。

我假设编译器可以最大限度地优化代码(否则,谈论性能就没有意义了)

如果编译示例中的循环时,
do\u sth
的主体可见,编译器很可能会将其内联,然后将
var
的赋值(以及
var
的堆栈空间分配)作为死代码删除,因此对于这种情况,开销实际上并不存在。如果
do\u sth
不能内联,那么函数调用的代价比int的声明更重要。如果函数可以内联,编译器很可能将第一个版本转换为第二个版本,即使
var
不是死代码。所以对于这样的例子,这真的不重要

如果您的变量是更复杂的类型(非POD类类型),这可能很重要。在这种情况下,第一个版本将为每个迭代调用一次构造函数和析构函数,而第二个版本将为每个迭代调用一次赋值运算符,并且只调用一次构造函数和析构函数。但是请注意,这并没有说明哪个版本更快(取决于这些方法的实现)。

找到ou的最佳方法