繁体   English   中英

在Java 8中找到高低

[英]Find high and low in Java 8

我正在测试在Java中的列表中搜索低值和高值的不同方法,我意识到使用stream()和parallelStream()方法的结果更慢且性能更差,而不仅仅是遍历列表......

这可能吗? 这怎么可能?

这是我的代码:

迭代整个数组:

    private HighLowTuple calculateIteratingWholeArray( List<Integer> arrayWithNumbers,         int from, int to )
        {

    // long start = System.currentTimeMillis();
    HighLowTuple result = new HighLowTuple( -1, Integer.MAX_VALUE );
    for( int i = from; i < to; i++ )
    {

        int value = arrayWithNumbers.get( i );

        if( value > result.high )
        {
            result.high = value;
        }

        if( value < result.low )
        {
            result.low = value;
        }

    }
    // long end = System.currentTimeMillis();
    // System.out.println( "duration internal calculateIteratingWholeArray from " + from +
    // " to + " + to + "  "
    // + ( end - start ) + " ms" );
    return result;
}

这里使用java 8流的代码:

     private HighLowTuple calculateUsingStreamParallel( List<Integer> arrayWithIntegers )
{
    HighLowTuple result = new HighLowTuple( -1, Integer.MAX_VALUE );

    Consumer<Integer> highlow = new Consumer<Integer>()
    {

        @Override
        public void accept( Integer number )
        {
            if( result.high < number )
                result.high = number;

            if( result.low > number )
                result.low = number;

        }
    };
    arrayWithIntegers.stream().parallel().forEach( highlow );
    return result;
}

在开始考虑性能之前,您应该考虑正确性 您正在使用并行流与自定义,有状态的Consumer ,该Consumer不是线程安全的:

if( result.high < number )
// if another thread updates ⟨high⟩ right at this point you might loose a value
    result.high = number;

if( result.low > number )
// again, possible loss of values here
    result.low = number;

此外,除非您已将变量HighLowTuple.highHighLowTuple.lowvolatile ,否则当您在没有同步的情况下使用多线程时,JVM的优化可能会导致更多的更新丢失。 但是如果你声明它们是volatile你不应该对性能降低感到惊讶(但仍然有不正确的代码)。


解决方案是首先了解API。 你已经重新发明了这个轮子,因为已经有一种简洁的方法可以在Java 8中找到高低:

IntSummaryStatistics s = arrayWithIntegers.stream()
  .parallel().mapToInt(Integer::intValue).summaryStatistics();
// if you still like your tuple class:
return new HighLowTuple(s.getMax(), s.getMin());

但是,当然,如果你有一个数组int值,将会变得更有效地使用一个IntStream出来的,而不是使搁着的CollectionInteger

IntSummaryStatistics s = IntStream.of(array).parallel().summaryStatistics();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM