我试图在几种可能的做法之间做出决定。比如说,我的函数有许多 if() 块,它们对数据起作用,这是它们独有的。
我应该在块内声明和初始化本地(对于块)数据吗?这是否有运行时性能成本(由于堆栈中的运行时分配)?
或者我应该在函数入口声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
或者我应该将 if() 块分隔在不同的函数中,即使它们只有几行长并且在程序中只使用了一个?
还是我忽略了另一个更清洁的选择?这个问题甚至可以以当前的一般形式回答吗?
我试图在几种可能的做法之间做出决定。比如说,我的函数有许多 if() 块,它们对数据起作用,这是它们独有的。
我应该在块内声明和初始化本地(对于块)数据吗?这是否有运行时性能成本(由于堆栈中的运行时分配)?
或者我应该在函数入口声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
或者我应该将 if() 块分隔在不同的函数中,即使它们只有几行长并且在程序中只使用了一个?
还是我忽略了另一个更清洁的选择?这个问题甚至可以以当前的一般形式回答吗?
我应该在块内声明和初始化本地(对于块)数据吗?
绝对:这往往会使程序更具可读性。
这是否有运行时性能成本(由于堆栈中的运行时分配)?
否:所有分配都是预先完成的 - 堆栈上的空间在进入函数时为所有分支中的变量保留,而不是在进入分支时。此外,这甚至可以为您节省一些空间,因为为非重叠分支中的变量分配的空间可以被编译器重用。
或者我应该在函数入口声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
不,这不是更快,并且可能会稍微浪费一些。
或者我应该将 if() 块分隔在不同的函数中,即使它们只有几行长并且在程序中只使用了一个?
这可能会对程序的可读性产生负面影响。
保持变量的范围尽可能小是一个好习惯。
如果您在开始时一次性声明所有变量,并且您不
经常在程序中使用它们。没用,需要更多内存。
此外,保持较小范围的另一个优点是您可以再次重用
相同的名称。(您不必每次
做一些琐碎的事情时都发明新名称)。
在您声明的选项中,声明和初始化块内的本地(对于块)数据将满足您的目的。忘记其余的事情。
为了完整性;另一个通常不太重要的考虑因素是堆栈填充控制/打包,如果您不预先声明所有内容,这在直观上会更加困难。
有关更多信息,请参阅此内容,尽管在任何人做任何疯狂的事情之前让我强调以下段落:
通常,对于您的 C 程序中的少量标量变量,通过更改声明顺序来消除您可以获得的几个字节并不能为您节省足够的重要性。当应用于非标量变量时,该技术变得更加有趣——尤其是结构。
现在是关于性能的答案。
我应该在块内声明和初始化本地(对于块)数据吗?这是否有运行时性能成本(由于堆栈中的运行时分配)?
局部变量的分配实际上是免费的。在大多数情况下,它确实是空闲的,因为堆栈指针的更新是在将值写入堆栈的同一条指令中执行的。释放也是免费的(当某些东西从堆栈中弹出时),或者在返回时完成一次(当创建堆栈帧时)。
或者我应该在函数入口声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
虽然分配实际上是免费的,但运行构造函数/析构函数却不是。虽然这不适用于原始类型的变量,但它几乎适用于所有用户定义的类型,包括智能指针等。如果您在函数的开头声明了一个智能指针,但只使用了一半时间,那么您构造并随后破坏了所需的两倍的智能指针。
此外,如果您声明一个变量,其中您有信息将其初始化为您的需要,您可以直接将其构造为您希望它具有的状态,而不是首先默认构造它只是为了在之后更改它的值(使用赋值运算符很多情况)。因此,从性能的角度来看,您应该总是延迟声明变量,并且只在需要它们的块中声明。
或者我应该将 if() 块分隔在不同的函数中,即使它们只有几行长并且在程序中只使用了一个?
不,从性能的角度来看,这完全是矛盾的。每个函数调用都有开销,我认为大多数时候它在 10 到 20 个周期之间。你可以在那个时候做很多计算。