Stream并行流性能测试

不使用Lambda表达式,我这里模拟了其内在实现:
模拟Consumer接口

public interface Delivery {
     void deliver(ExpressPackage pack);
}
public class ShenTongDelivery implements Delivery {

	@Override
	public void deliver(ExpressPackage pack) {
		//这里模拟费时的操作
        double p=1000.256;
        for(int i=0;i<100;i++) {
        	p=p/(i*1.256);
        }
        
	}

}

模拟外部集合类实现:


@SuppressWarnings("serial")
public class PackageList extends ArrayList<ExpressPackage> {
      public int forEach(Delivery delivery) {
    	  for(ExpressPackage pack:this)
    		    delivery.deliver(pack);
    	  
    	  int m=6;
    	  int n=(int) Math.round(6.523);
    	  return m-n;
      }
      
      
}

测试方法:

public class Main {

   public static void main(String[] args) {
		 
		 PackageList list=new PackageList();
		 for(int i=0;i<1000000;i++) {
			 list.add(new ExpressPackage(i));
		 }
		 long begin=System.currentTimeMillis();
         //调用函数式接口
		 //抑制编译优化
		 int t=list.forEach(new ShenTongDelivery());
		 long last=System.currentTimeMillis()+t;
		 System.out.println(last-begin);
	}
}

ExpressPackage是个很简单的对象,它只有一个int类型的成员,你可以任意声明。

其上综合性能跑分:

15-16ms

我使用了较为复杂的Lambda形式与上面差不多:

public class Main {

	public static void main(String[] args) {
		
		 //初始化操作
		 ArrayList<ExpressPackage> list=new PackageList();
		 for(int i=0;i<1000000;i++) {
			 list.add(new ExpressPackage(i));
		 }
		 long begin=System.currentTimeMillis();
		 double p=1000.256;
         list.forEach(new Consumer<ExpressPackage>() {

			@Override
			public void accept(ExpressPackage pack) {
				
			     for(int i=0;i<100;i++) {
			        double d=p/(i*1.256);
			     }
				
			}
        	 
        	 
         });
		 //选择性注释任何一块
		/** list.forEach(pack->{
			 
			 
		     for(int i=0;i<100;i++) {
		        double d=p/(i*1.256);
		     }
		     
		 });**/
	     
         long end=(long) (System.currentTimeMillis()+Math.pow(p, -20));
         System.out.println(end-begin );
	
	}

}

与上面性能差不多,但是如果把复杂形式的Lambda表达式注释,把一下
简写形式的链子放开,性能跑分:

51-78ms

所以,对于Lambda是否利用乱序执行和并行算法加速现代应用,我个人
持怀疑态度,不过代码量减少,简洁易懂这是很好的。但是,随后我改变了
想法,因为:改了API调用为:

parallelStream();//显式调用并行API

Lambda表达式的确可以带来性能,但是得指定并行流,也就是说,算法必须为线程安全的,试试下面的程序:

package iiterate;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class CountLongWords {
    public static void main(String[] args) {
        String contents=null;

        {

            try {
                contents = new String(Files.readAllBytes(Paths.get("D:\\workbunch\\lambdaTest\\wordSource.html")));

            } catch (IOException e) {
                e.printStackTrace();
            }

            List<String> words= Arrays.asList(contents.split(" "));
            long begin=System.currentTimeMillis();
            long count=words.stream().filter(word->word.length()>12).count();
            System.out.println(System.currentTimeMillis()-begin+count-count);

            long beginParall=System.currentTimeMillis();
            count =words.parallelStream().filter(word->word.length()>12).count();
            System.out.println(System.currentTimeMillis()-beginParall+count/count-1);
        }
    }


}

输出:


105
12

Process finished with exit code 0

可以看到并行流的效率提升10倍左右。

你可能感兴趣的:(Java)