Java:声明大小为 n 的数组需要多长时间?
在Java中声明一个大小为n的数组的运行时间是多少?我想这取决于内存是否在垃圾回收时清零(在这种情况下它可能是 O(1) )或在初始化时清零(在这种情况下它必须是 O(n) )。
What is the running time of declaring an array of size n in Java? I suppose this would depend on whether the memory is zero'ed out on garbage collection (in which case it could be O(1) ) or on initialization (in which case it'd have to be O(n) ).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是
O(n)
。考虑这个简单的程序:生成的字节码是:
要查看的指令是
newarray
指令(只需搜索newarray
)。来自虚拟机规范:由于每个元素都被初始化,因此需要
O( n) 时间。
编辑
查看提供的链接,可以在恒定时间内使用默认值实现数组初始化。所以我想这最终取决于 JVM。您可以做一些粗略的基准测试来看看是否是这种情况。
It's
O(n)
. Consider this simple program:The bytecode generated is:
The instruction to take a look at is the
newarray
instruction (just search fornewarray
). From the VM Spec:Since each element is being initialized, it would take
O(n)
time.EDIT
Looking at the link amit provided, it is possible to implement array-initialization with a default value, in constant time. So I guess it ultimately depends on the JVM. You could do some rough benchmarking to see if this is the case.
JRE1.6 上的一个小型非专业基准测试:
给出了以下结果:
所以我假设 O(n)。
当然,这还不够确定,但这是一个提示。
A small none professional benchmark on JRE1.6:
gave the following result:
so I assume O(n).
of course, it is not enough to be sure, but it's a hint.
我很确定它是 O(n),因为内存是在分配数组时初始化的。它不应该高于 O(n),而且我看不出有什么办法可以使它小于 O(n),所以这似乎是唯一的选择。
进一步详细说明,Java 在分配时初始化数组。没有办法在不遍历内存区域的情况下将其清零,并且该区域的大小决定了指令的数量。因此,下界是 O(n)。此外,使用比线性慢的归零算法是没有意义的,因为存在线性解,因此上限必须是 O(n)。因此,O(n) 是唯一有意义的答案。
不过,只是为了好玩,想象一下一个奇怪的硬件,其中操作系统可以控制各个内存区域的电源,并且可以通过关闭然后打开电源来将某个区域归零。这看起来像是 O(1) 。但在效用消失之前,区域只能这么大(不想失去一切),因此要求将区域归零仍然是 O(n) 且除数很大。
I am pretty sure that it is O(n), as the memory is initialized when the array is allocated. It should not be higher than O(n), and I can see no way to make it less than O(n), so that seems the only option.
To elaborate further, Java initializes arrays on allocation. There is no way to zero a region of memory without walking across it, and the size of the region dictates the number of instructions. Therefore, the lower bound is O(n). Also, it would make no sense to use a zeroing algorithm slower than linear, since there is a linear solution, so the upper bound must be O(n). Therefore, O(n) is the only answer that makes sense.
Just for fun, though, imagine a weird piece of hardware where the OS has control over the power to individual regions of memory and may zero a region by flipping the power off and then on. This seems like it would be O(1). But a region can only be so large before the utility disappears (wouldn't want to lose everything), so asking to zero a region will still be O(n) with a large divisor.
我们来测试一下。
我的 Linux 笔记本电脑(i7-4600M @ 2.90GHz)上的结果:
所以它显然看起来像
O(n)
,但是看起来它还切换到了大约 500 万个元素的更有效的方法。Let's just test it.
And the results on my linux laptop (i7-4600M @ 2.90GHz):
So it clearly looks like
O(n)
, but it also looks like it switches to a more efficient method at around 5 million elements.