在整数数组中找到最小最大值,性能问题

迪尔

我在这里写了这两个方法来找到最小值和最大值。#2是基于这个帖子这个答案在这里

private static Pair classicMinMax(int[] elements) {
    int min = MAX_VALUE;
    int max = MIN_VALUE;

    for (int i = 0; i < elements.length; i++) {
        int e = elements[i];
        if (e < min) min = e;
        if (e > max) max = e;
    }
    return new Pair(min, max);

}

private static Pair divideAndConquer(int[] elements) {
    int min = MAX_VALUE;
    int max = MIN_VALUE;

    for (int i = 0; i < elements.length - 1; i += 2) {
        int a = elements[i];
        int b = elements[i + 1];

        if (a > b) {
            if (b < min) min = b;
            if (a > max) max = a;
        } else {
            if (a < min) min = a;
            if (b > max) max = b;
        }
    }

    if (elements.length % 2 != 0) {
        int lastElement = elements[elements.length - 1];
        if (lastElement < min) min = lastElement;
        if (lastElement > max) max = lastElement;
    }
    return new Pair(min, max);
}

如果我运行这样的简单基准测试:

@Test
public void timingsBoth() throws Exception {

    int size = 1000;

    for (int i = 1000; i < 10_000; i += 1000) {
        int arraySize = size * i;
        System.out.println("step is " + arraySize);

        List<Integer> list = new ArrayList<>(arraySize);
        int[] elements = new int[arraySize];
        for (int k = 0; k < arraySize; k++) {
            list.add(k);
        }

        Collections.shuffle(list);
        Integer[] integers = list.toArray(new Integer[0]);
        for (int k = 0; k < arraySize; k++) {
            elements[k] = integers[k];
        }

        long start = currentTimeMillis();
        classicMinMax(elements);
        long stop = currentTimeMillis();
        long result = stop - start;
        System.out.println("classic is " + result);

        start = currentTimeMillis();
        divideAndConquer(elements);
        stop = currentTimeMillis();
        result = stop - start;
        System.out.println("divideAndConquer is " + result);
    }
}

}

我通常会得到这个结果:

step is 1000000 classic is 8 divideAndConquer is 11 step is 2000000 classic is 2 divideAndConquer is 5 step is 3000000 classic is 11 divideAndConquer is 17 step is 4000000 classic is 5 divideAndConquer is 10 step is 5000000 classic is 4 divideAndConquer is 16 step is 6000000 classic is 6 divideAndConquer is 14 step is 7000000 classic is 6 divideAndConquer is 18 step is 8000000 classic is 8 divideAndConquer is 20 step is 9000000 classic is 8 divideAndConquer is 24

我弄错了算法吗?我期待至少有类似的结果。

迪尔

好的,根据评论中的建议,我认为我做了一个更好的基准测试。我使用的是Java Microbenchmark Harness我以前从未使用过它,所以我的测试基于这个方便的教程

我所做的是创建一个 JMH 测试,如下所示:

public class MinMaxBenchmark {

    @State(Scope.Benchmark)
    public static class MyState {

        int arraySize = 50_0000;
        int[] elements = new int[arraySize];

        @Setup(Level.Trial)
        public void doSetup() {
            List<Integer> list = new ArrayList<>(arraySize);
            for (int k = 0; k < arraySize; k++) {
                list.add(k);
            }
            Collections.sort(list);
            Integer[] integers = list.toArray(new Integer[0]);
            for (int k = 0; k < arraySize; k++) {
                elements[k] = integers[k];
            }

        }
    }


    @Benchmark @BenchmarkMode(Mode.SampleTime   ) @OutputTimeUnit(TimeUnit.MILLISECONDS)
    public Pair classic(MyState state) {
        return classicMinMax(state.elements);
    }
    @Benchmark @BenchmarkMode(Mode.SampleTime) @OutputTimeUnit(TimeUnit.MILLISECONDS)
    public Pair divide(MyState state) {
        return divideAndConquer(state.elements);
    }

}

我特别注意在@State使用@Setup初始化方法的基准测试之外创建数组(输入数据)比我写的@Benchmark方法。我在返回结果时非常小心,因此可以避免死代码(全部在教程中)。

通过这种设置,我进行了多次试验。这是最后一次尝试:

Benchmark Mode Cnt Score Error Units MinMaxBenchmark.classic sample 994028 0.202 ± 0.001 ms/op MinMaxBenchmark.classic:classic·p0.00 sample 0.153 ms/op MinMaxBenchmark.classic:classic·p0.50 sample 0.180 ms/op MinMaxBenchmark.classic:classic·p0.90 sample 0.259 ms/op MinMaxBenchmark.classic:classic·p0.95 sample 0.311 ms/op MinMaxBenchmark.classic:classic·p0.99 sample 0.409 ms/op MinMaxBenchmark.classic:classic·p0.999 sample 0.567 ms/op MinMaxBenchmark.classic:classic·p0.9999 sample 0.942 ms/op MinMaxBenchmark.classic:classic·p1.00 sample 2.617 ms/op MinMaxBenchmark.divide sample 1226029 0.164 ± 0.001 ms/op MinMaxBenchmark.divide:divide·p0.00 sample 0.126 ms/op MinMaxBenchmark.divide:divide·p0.50 sample 0.149 ms/op MinMaxBenchmark.divide:divide·p0.90 sample 0.201 ms/op MinMaxBenchmark.divide:divide·p0.95 sample 0.230 ms/op MinMaxBenchmark.divide:divide·p0.99 sample 0.327 ms/op MinMaxBenchmark.divide:divide·p0.999 sample 0.522 ms/op MinMaxBenchmark.divide:divide·p0.9999 sample 0.945 ms/op MinMaxBenchmark.divide:divide·p1.00 sample 3.199 ms/op

实际上,鸿沟仅在p1.00 上失败(我需要找到含义)。

所以我想这是我处理基准测试的方式的问题。

感谢您在评论中的帮助,尤其是@alfasin。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在PHP数组中找到最大值

来自分类Dev

在Java整数数组列表中找到最小值的递归函数

来自分类Dev

在数组中找到最小值和最大值时出现Stackoverflow错误?

来自分类Dev

Masm32。在数组中找到最小值和最大值

来自分类Dev

在多维字典中找到最大值,最小值

来自分类Dev

在整数数组列表中找到最大的数字序列

来自分类Dev

在无序整数数组中找到最大对和的函数

来自分类Dev

在整数数组中找到最大的数字javascript

来自分类Dev

如何从整数列表中找到最大值

来自分类Dev

在键是数组的对象中找到最大值?

来自分类Dev

如何在Swift对象数组中找到最大值?

来自分类Dev

如何在numpy数组列中找到最大值?

来自分类Dev

在一维数组中找到局部最大值

来自分类Dev

在排除索引的数组中找到最大值

来自分类Dev

如何在numpy数组列中找到最大值?

来自分类Dev

在多维数组中找到最大值并返回父键

来自分类Dev

如何在数组中找到最大值

来自分类Dev

如何在多维数组中找到最大值

来自分类Dev

如何在numpy数组中找到对应的最大值

来自分类Dev

如何在numpy中的3d数组中找到最小值和最大值,并将结果分组?

来自分类Dev

如何在不使用if语句的情况下在数组中找到最大值和最小值?

来自分类Dev

如何在数组以及对应的日期中找到最大值和最小值

来自分类Dev

找到最大值后,在单独的列中找到后续的最小值

来自分类Dev

C ++从相同大小的两个不同整数数组中找到最小商

来自分类Dev

如何从列中找到最大值

来自分类Dev

如何从字典中找到最大值?

来自分类Dev

在循环中找到最大值

来自分类Dev

在元组向量中找到最大值

来自分类Dev

如何从结构中找到最大值?

Related 相关文章

热门标签

归档