【问题标题】:Time complexity measure of JDK class methodsJDK类方法的时间复杂度度量
【发布时间】:2013-03-28 19:36:27
【问题描述】:

是否有一种既定的方法来衡量(或获取现有的衡量标准)JDK 类方法的复杂性? javap代表时间复杂度和程度。特别是,我对Arrays.sort() 的复杂性以及其他一些集合操作方法感兴趣。

例如我正在尝试比较两种实现的性能,一种使用Arrays.sort(),一种不使用。 javap 反汇编不会返回更多步骤(两倍),但我不确定是否排除了Arrays.sort() 步骤。 IOW,一种方法的javap 是否包括在该方法内或仅针对该方法调用的方法的递归度量?

另外,有没有一种方法可以在不修改和重新编译 Java 代码本身的情况下,找出在特定参数上调用某个基本 Java 方法时完成了多少次循环迭代?例如。测量Arrays.sort('A', 'r', 'T', 'f')的迭代次数?

【问题讨论】:

    标签: java performance time-complexity javap


    【解决方案1】:

    我不希望javap 能代表实际速度。

    Javadoc 指定了算法的复杂性,但如果您关心常数因子,则绝对无法实际比较常数因子,除非与实际的 benchmarks

    当在原始数组上调用Arrays.sort 时,您无法获得任何有关所做操作的信息,但是通过传递一个计算调用次数的自定义Comparator,您可以计算排序时进行的比较次数一个对象数组。 (也就是说,对象数组使用不同的排序算法进行排序——特别是稳定算法——而原始数组使用 Quicksort 变体进行排序。)

    【讨论】:

    • 他们没有在该页面上为Caliper 列出任何下载
    • 卡尺目前有点不稳定;他们正在完全重写——但重点仍然是你需要实际运行排序和时间。
    • 所以基本上是用实际数据进行抽样?
    • 没错。 Java 在 JIT 中做了如此多的优化,任何仅仅通过查看代码的猜测几乎肯定会大错特错。
    • System.nanoTime() 是衡量“已用时间”的正确方法。
    【解决方案2】:

    您可以使用javap 的输出来确定循环发生的位置,您希望找到goto 指令。这个post 给出了对该标识的全面解释。

    来自帖子:

    在考虑任何循环启动/退出检测之前,您应该 查看进入、退出和继任者的定义。 虽然一个循环只有一个入口点,但它可能有多个 退出点和/或多个继任者,通常由中断引起 语句(有时带有标签)、返回语句和/或 异常(是否明确捕获)。虽然你没有提供细节 关于你正在调查的仪器类型,它是 当然值得考虑你想在哪里插入代码(如果那是 你想做什么)。通常,某些仪器可能必须 在每个退出语句之前或代替每个后继语句之前完成 (在这种情况下,您必须移动原始语句)。

    【讨论】:

    • 但是一种方法的javap 是否包括在该方法内或仅为该方法调用的方法的递归测量?
    • @amphibient 好问题。我不知道,但从研究的角度来看,我确实很感兴趣。
    • @amphibient: 只是为了那个方法。
    【解决方案3】:

    Arrays.sort() 对于原语使用调整的快速排序。对于 Object 使用合并排序(但这取决于实现)。

    发件人:Arrays

    例如,sort(Object[]) 使用的算法不必是 一个归并排序,但它必须是稳定的

    【讨论】:

    • @downvoter:你应该评论。OP询问比较排序方法。通过解释实际用作答案的排序方法有什么问题?
    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多