[英]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.high
和HighLowTuple.low
为volatile
,否则当您在没有同步的情况下使用多线程时,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
出来的,而不是使搁着的Collection
的Integer
:
IntSummaryStatistics s = IntStream.of(array).parallel().summaryStatistics();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.