如果我在堆栈上使用零填充初始化语法定义以下数组:
int arr[ 10 ] = { 0 };
运行时间是常数还是线性的?
我的假设是这是一个线性运行时——我的假设只是针对calloc
必须遍历每个字节才能将其填充为零的事实
如果你也能提供为什么,而不仅仅是订单xxx,那将是巨大的!
运行时的数组大小是线性的。
为了了解原因,这里有一个memset的示例实现,它将数组初始化为任意值。在汇编语言级别,这与代码中的内容没有什么不同。
void *memset(void *dst, int val, size_t count) {
unsigned char *start = dst;
for (size_t i = 0; i < count; i++)
*start++ = value;
return dst;
}
当然,编译器通常会使用内部函数一次设置多个数组元素。根据数组的大小以及对齐和填充等因素,这可能会使数组长度上的运行时更像楼梯,步长基于向量长度。对于数组大小的微小差异,这将有效地使运行时保持不变,但一般模式仍然是线性的。
这实际上是冰山问题的一个提示。您真正要问的是初始化数组的顺序是什么(Big Oh)。从本质上讲,代码在数组的每个元素中循环,并将它们设置为零。你可以写一个for循环来做同样的事情。
该循环的数量级为O(n),也就是说,在循环中花费的时间与初始化的元素数量成比例增加。
如果硬件支持一条指令,该指令说将从位置X到Y的所有字节设置为零,并且该指令在M个指令周期中工作,并且无论字节数设置为零如何,M都从未改变,那么这将是k阶或O(k)阶。
通常,O(k)可能被称为常数时间,O(n)可能被称作线性时间。