char buffer[1000] = {0};
这会将所有1000个元素初始化为0.这是恒定的时间吗?如果没有,为什么?
似乎编译器可以根据以下事实将其优化为O(1):
请注意,答案对于任何编译器都是通用的,但我特别感兴趣的是在Windows上的MSVC编译器(任何版本)上测试的答案。
奖励积分:非常感谢有关此细节的任何文章,白皮书等的链接。
答案 0 :(得分:8)
如果它在一个函数内部,不,它不是恒定的时间。
你的第二个假设是不正确的:
“数组位于堆栈上,这意味着可执行文件可能包含可执行文件数据段(在Windows上)中的这些数据,作为已填充0的数据块。”
堆栈尚未填充零。它充满了以前函数调用中的垃圾剩余。
因此无法在O(1)
中执行此操作,因为它必须将其归零。
答案 1 :(得分:6)
它只能作为全局变量O(1)。如果它是局部变量(在堆栈上),则为O(n),其中n是数组的大小。
Stack是一个共享内存,你需要主动为零,总是希望在那里有1000个零。您定义的数组不是作为指向数据段的指针实现的,它是堆栈上的1000个变量,必须在O(1000)中初始化。
编辑:Dani是对的,我必须修改我的声明:如果它是一个全局数组,它会在程序启动时初始化。而且它也是O(n)。答案 2 :(得分:4)
它永远不会是恒定时间,全球与否。编译器初始化它是真的,但操作系统必须将所有文件加载到内存中,这需要O(n)
时间。
答案 3 :(得分:1)
数组位于堆栈上,这意味着可执行文件可能包含可执行文件数据段(在Windows上)中的数据,作为已填充0的数据块。
如果你进入定义数组的函数怎么办?全局DATA段需要为每个函数调用提供此数组的副本,以允许每个函数都有自己的数组来处理。编译器必须运行您的代码以确定将发生的最大递归。
当你的程序中有多个线程并且每个调用foo时会发生什么?突然间你在DATA中共享了必须被锁定的内容。锁定可能会导致比摆脱初始化更多的性能问题。
我也不会太担心它。大多数平台都有相当有效的零填充内存方式。除非你对它进行分析并发现问题,否则不要冒汗。
答案 4 :(得分:0)
正如其他人所指出的那样,假设2是错误的。堆栈变量在运行时在O(1)时间内分配,但除非您正在运行调试版本,否则通常不会初始化。
PUSH ebp
MOV ebp, esp
SUB esp, 10
// function body code goes here
这里,堆栈指针'esp'减10,为某些局部函数变量腾出空间。它们不是初始化......需要循环。
This文章似乎很友好。
答案 5 :(得分:-1)
如果它是全局静态,则此处的“常量”为零 - 初始化在COMPILE TIME完成。