併發程式設計:DEMO:比較Stream和forkjoin框架的效率

博風發表於2020-11-30

 目錄

一、主程式

二、Person類

三、forkjoin框架的任務

四、執行結果

五、總結


一、主程式

package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;

/**
 *  11.13、使用流處理大資料(比較Stream和forkjoin的效率)
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年11月30日 下午7:58:04
 * 
 */
public class M {

	public static void main(String[] args) {
		var ps = Person.generatorPersons(10000000);
		// 使用流
		var start = new Date();
		ConcurrentMap<String, List<Person>> collect = ps.parallelStream()
				.collect(Collectors.groupingByConcurrent(p -> p.getArea()));
		var end = new Date();
		System.out.println(collect.size() + ":Stream::Time:" + (end.getTime() - start.getTime()));
		// 使用fork/join框架
		start = new Date();
		var forkjoinMap = new ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>>();
		var personMapTask = new PersonMapTask(ps, forkjoinMap);
		ForkJoinPool.commonPool().invoke(personMapTask);
		end = new Date();
		System.out.println(forkjoinMap.size() + ":ForkJoinPool::Time:" + (end.getTime() - start.getTime()));

	}

}

二、Person類

package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 	Model
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年11月30日 下午7:30:02
 * 
 */
public class Person {

	private String name;

	private String area;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getArea() {
		return area;
	}

	public void setArea(String area) {
		this.area = area;
	}

	public static List<Person> generatorPersons(int size){
		String[] names = {"A","B","C"};
		String[] areas = {"北","上","深","杭"};
		var persons = new ArrayList<Person>();
		
		var random = new Random();
		for (int i = 0; i < size; i++) {
			var p = new Person();
			p.setName(names[random.nextInt(names.length)]);
			p.setArea(areas[random.nextInt(areas.length)]);
			persons.add(p);
		}
		return persons;
	}
}

三、forkjoin框架的任務

package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.RecursiveAction;

/**
 *  forkjoin框架的任務
 * @author jangle
 * @email jangle@jangle.xyz
 * @time 2020年11月30日 下午7:39:42
 * 
 */
public class PersonMapTask extends RecursiveAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private List<Person> persons;
	private ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>> personMap;

	public PersonMapTask(List<Person> persons, ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>> personMap) {
		super();
		this.persons = persons;
		this.personMap = personMap;
	}

	@Override
	protected void compute() {
		if (persons.size() < 1000) {
			for (Person person : persons) {
				ConcurrentLinkedDeque<Person> personList = personMap.computeIfAbsent(person.getArea(),
						area -> new ConcurrentLinkedDeque<Person>());
				personList.add(person);
			}
			return;
		}
		var t1 = new PersonMapTask(persons.subList(0, persons.size() / 2), personMap);
		var t2 = new PersonMapTask(persons.subList(persons.size() / 2, persons.size()), personMap);
		invokeAll(t1, t2);
	}

}

四、執行結果

4:::Time:872
4:::Time:624

五、總結

兩個解決方案的效率相近,forkjoin框架略高於Stream。但是,Stream使用方便,可以節省開發時間。

相關文章