【问题标题】:Is Array declaration linear time operation or constant time operation? [duplicate]数组声明是线性时间运算还是常数时间运算? [复制]
【发布时间】:2019-05-18 20:26:49
【问题描述】:
boolean[] arr = new boolean[n];

上述初始化的时间复杂度是多少?是 O(1) 还是 O(n)?我认为它是 O(1),因为程序只是向 JVM 请求一块大小为 n 的内存。在这种情况下,JVM(热点)实际上是如何分配内存的?

到目前为止,我已经查看了以下链接,但我并不清楚答案:

Thread-1 Thread-2

【问题讨论】:

    标签: java time-complexity big-o jvm-hotspot


    【解决方案1】:

    我认为一般它是O(n),因为声明的数组需要使用默认值为零,在您的情况下为false

    但是虚拟机也可以证明这个数组不是立即读取的,即有人首先将所有元素写入其中,然后只有在之后才读取它们。在这种情况下,复杂性将是O(1),因为您实际上并没有做任何事情(数组本身内没有放置默认值) - 因此是恒定的。

    例如,这就是 java-11Collection::toArray 发生的事情,通过:

    default <T> T[] toArray(IntFunction<T[]> generator) {
        return toArray(generator.apply(0));
    } 
    

    所以当你有类似的东西时:

    List.of(1, 2, 3, 4)
        .toArray(x -> new Integer[x]);
    

    该实现实际上将执行new Integer[0] 并使用它加上一些System.arrayCopy,而不是推断的new Integer[4]。这样做是因为 VM 可以prove 不需要归零,因此完全跳过它。

    【讨论】:

    • 感谢@Eugene 的撰写和链接。本质上,当多项式中的剩余项优于 O(n) 时,(数据结构操作的)时间复杂度分析应该意识到并考虑任何新的数组声明?
    • 今天的 HotSpot 可能不会发生这种情况,但原则上,当 JVM 知道新的新内存已经清零时,它也有可能跳过清零。例如。某些操作系统允许在分配新内存时请求归零内存,因为出于安全原因,它们无论如何都会对页面进行归零。
    • @Holger 甚至AlwaysPreTouch 都可能。好点
    猜你喜欢
    • 1970-01-01
    • 2011-04-26
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2021-04-27
    相关资源
    最近更新 更多