栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Java中,相同代码块的运行时间不同。这是为什么?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Java中,相同代码块的运行时间不同。这是为什么?

基准测试错误。错误的非详尽清单:

  • 没有预热 :单次测量几乎总是错误的;
  • 在单个方法中混合几个代码路径 :我们可能开始使用仅适用于该方法中第一个循环的执行数据来编译该方法;
  • 来源是可预测的 :如果循环编译,我们实际上可以预测结果;
  • 结果消除了死代码 :如果循环编译,我们可以将循环丢掉

这可以说是用jmh正确地做到的:

@OutputTimeUnit(TimeUnit.NANOSECONDS)@BenchmarkMode(Mode.AverageTime)@Warmup(iterations = 3, time = 1)@Measurement(iterations = 3, time = 1)@Fork(10)@State(Scope.Thread)public class Longs {    public static final int COUNT = 10;    private Long[] refLongs;    private long[] primLongs;        @Setup    public void setup() {        primLongs = new long[COUNT];        for (int i = 0; i < COUNT; i++) { primLongs[i] = 12l;        }        refLongs = new Long[COUNT];        for (int i = 0; i < COUNT; i++) { refLongs[i] = 12l;        }    }    @GenerateMicroBenchmark    public long[] prim_baseline() {        long[] d = new long[COUNT];        System.arraycopy(primLongs, 0, d, 0, COUNT);        return d;    }    @GenerateMicroBenchmark    public long[] prim_sort() {        long[] d = new long[COUNT];        System.arraycopy(primLongs, 0, d, 0, COUNT);        Arrays.sort(d);        return d;    }    @GenerateMicroBenchmark    public Long[] ref_baseline() {        Long[] d = new Long[COUNT];        System.arraycopy(refLongs, 0, d, 0, COUNT);        return d;    }    @GenerateMicroBenchmark    public Long[] ref_sort() {        Long[] d = new Long[COUNT];        System.arraycopy(refLongs, 0, d, 0, COUNT);        Arrays.sort(d);        return d;    }}

…产生:

Benchmark        Mode   Samples         Mean   Mean error    Unitso.s.Longs.prim_baseline     avgt        30       19.604        0.327    ns/opo.s.Longs.prim_sort         avgt        30       51.217        1.873    ns/opo.s.Longs.ref_baseline      avgt        30       16.935        0.087    ns/opo.s.Longs.ref_sort          avgt        30       25.199        0.430    ns/op

在这一点上,您可能会开始怀疑为什么排序

Long[]
和排序
long[]
会花费不同的时间。答案在于
Array.sort()
重载:OpenJDK通过不同的算法(使用TimSort的引用,使用双数据点快速排序的基元)对基元数组和引用数组进行排序。这是使用选择另一个算法的亮点
-Djava.util.Arrays.useLegacyMergeSort=true
,这又落到了合并排序的参考上:

Benchmark        Mode   Samples         Mean   Mean error    Unitso.s.Longs.prim_baseline     avgt        30       19.675        0.291    ns/opo.s.Longs.prim_sort         avgt        30       50.882        1.550    ns/opo.s.Longs.ref_baseline      avgt        30       16.742        0.089    ns/opo.s.Longs.ref_sort          avgt        30       64.207        1.047    ns/op

希望这有助于解释差异。

上面的解释几乎没有涉及排序的性能。当使用不同的源数据(包括可用的预排序子序列,它们的模式和游程长度,数据本身的大小)呈现时,性能会有很大不同。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/574124.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号