欢迎光临
我们一直在努力

程序员在Java 8中找到高潮和低潮 – java

程序员面试经验

我正在测试以各种方式在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一起使用:

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.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而不是绕开CollectionInteger效率会更高:

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

在Java Swing中输入JButton的键焦点? – java

如何在Java Swing中使JButton的Enter键成为焦点?我已经这样做了btn_Login.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("enter key pre…

在Java 8中,为什么ArrayList的默认容量现在为零? – java

我记得,在Java 8之前,ArrayList的默认容量为10。出乎意料的是,对默认(无效)构造函数的评论仍然显示:Constructs an empty list with an initial capacity of ten.来自ArrayList.java:/** * Shared empty array instance used for defau…

在Java 8流中,如何过滤掉不是枚举有效值的字符串? – java

我有一个枚举,我称之为对我的应用程序重要的安全权限的Permission。在数据库中,用户可能具有与我的应用程序无关的其他权限。从数据库中读取用户时,我得到一个List<String>,并且我想建立一个List<Permission>,而忽略了那些不是枚举值的字符串。public enum Permission { ADMIN, US…

Java:线程池如何将线程映射到可运行对象 – java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? – java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

赞(0)
未经允许不得转载: 京大飞辅助网程序员面试-区块链javago面经 » 程序员在Java 8中找到高潮和低潮 – java

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址