我正在考虑几种可能的做法。比如说,我的函数有许多if()块,它们在数据上工作,这些数据对它们来说是独特的。
我应该在块内部声明和初始化局部数据吗?这会导致运行时性能成本(由于在堆栈中运行时分配)吗?
还是应该在函数入口处声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
还是应该将if()块分离成不同的函数,即使它们只有几行代码并且只在程序中使用一次?
还是我忽略了另一个更加清晰的选项?当前的问题是否可以回答?
我正在考虑几种可能的做法。比如说,我的函数有许多if()块,它们在数据上工作,这些数据对它们来说是独特的。
我应该在块内部声明和初始化局部数据吗?这会导致运行时性能成本(由于在堆栈中运行时分配)吗?
还是应该在函数入口处声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
还是应该将if()块分离成不同的函数,即使它们只有几行代码并且只在程序中使用一次?
还是我忽略了另一个更加清晰的选项?当前的问题是否可以回答?
我是否应该在块内声明和初始化局部数据?
绝对是的:这可以使程序更易读。
这样做会有运行时性能成本(由于在堆栈中运行时分配)吗?
不会:所有的分配都是预先完成的——在进入函数时,堆栈上的空间已经被保留给了所有分支中的变量,而不是在进入分支时才进行分配。此外,这甚至还可以节省一些空间,因为编译器可以重复使用非重叠分支中分配给变量的空间。
或者我应该在函数入口处声明和/或初始化所有变量,以便在一个、可能更快的操作块中完成?
不,这不会更快,而且可能浪费一些空间。
或者我应该将 if() 块分开放在不同的函数中,即使它们只有几行,而且在程序中只使用了一次?
那可能会对程序的可读性产生负面影响。
尽可能保持 变量范围 较小是一个好的实践。
如果你一次性在开始时声明所有变量,并且在程序中不经常使用它们,那么这没有用,会占用更多的内存。
此外,保持作用域较小的另一个优点是可以再次重复使用相同的名称。(您不必每次执行琐碎的操作时都发明新名称)。
在你提出的选项中,声明并初始化块内部的局部数据是能够满足你目的的最好方法。忘记其他的事情。
为了完整性,另一个通常不太重要但需要考虑的问题是堆栈填充控制/打包,如果您没有事先声明所有内容,则这更难以直观理解。
请参见this获取更多信息,但在任何人做任何疯狂的事情之前,请让我强调以下段落:
通常,在您的C程序中,标量变量数量很少,通过改变声明顺序来获得的几个字节并不能节省足够的空间。当应用于非标量变量(尤其是结构体)时,该技术变得更加有趣。
现在来谈论性能问题。
我应该在块内部声明和初始化本地数据吗?这会有运行时性能成本(由于在堆栈中运行时分配)吗?
本地变量的分配几乎是免费的。在大多数情况下,它确实是免费的,因为堆栈指针的更新是在将值写入堆栈的同一条指令中执行的。释放也是免费的(当从堆栈中弹出某些内容时),或者在返回时进行一次(当创建了一个堆栈帧时)。
还是我应该在函数入口处声明和/或初始化所有变量,以便在一个可能更快的操作块中完成?
虽然分配几乎是免费的,但运行构造函数/析构函数不是。虽然这不适用于原始类型的变量,但它适用于几乎所有用户定义的类型,包括智能指针等。如果您在函数开头声明一个智能指针,但只使用一半的时间,则会构造并随后销毁两倍于所需的智能指针。
此外,如果您声明一个变量,并且已经有了初始化它所需的信息,那么您可以直接构造它以达到您想要的状态,而不是先默认构造它,然后再使用赋值运算符在许多情况下更改其值。因此,从性能的角度来看,您应该尽可能晚地声明变量,并且仅在需要它们的块中声明。