【问题标题】:Implementing Parallel Stream to get all the student details实施并行流以获取所有学生详细信息
【发布时间】:2018-06-08 18:41:44
【问题描述】:

我编写了一个服务来获取所有班级学生的完整详细信息。该服务运行良好,但问题是获取完整详细信息所需的时间太长。我的代码如下所示

List<StudentsDetails> allStudentsDetails = Lists.newArrayList();

List<ClassDetails> allClassDetailsDetails = getAllClassDetails();

allClassDetailsDetails.forEach(classDetailsDetails-> {
    StudentsDetails studentsDetails = new StudentsDetails();
    studentsDetails.setClassName(classDetailsDetails.getClassName());
    List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
    studentsDetails.setAllStudents(allStudents);        
    allStudentsDetails.add(studentsDetails);
});

我的问题

在这种情况下使用Java8并行流是否很好,是否真的可以提高性能,以及如何在这种方法中实现并行流。

【问题讨论】:

  • 测试一下。但不确定它会带来更好的性能,因为我相信性能不足通常来自数据层而不是应用程序层。

标签: list parallel-processing java-8 java-stream


【解决方案1】:

这是您并行化操作的方式,但无法保证性能优势,因为它还取决于外部数据库。

Function<ClassDetails, StudentsDetails> fetchStudentDetials = classDetailsDetails -> {
    StudentsDetails studentsDetails = new StudentsDetails();
    studentsDetails.setClassName(classDetailsDetails.getClassName());
    List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
    studentsDetails.setAllStudents(allStudents);
    return studentsDetails;
};

List<StudentsDetails> allStudentsDetails = allClassDetailsDetails
        .parallelStream()
        .map(fetchStudentDetials)
        .collect(toList());

【讨论】:

  • 感谢您的回复.....在我的方法中实现并行流是否有任何副作用......
  • 没有。另请注意,只有当您有大量集合或长时间运行的任务时,并行流才会受益。请看@Mạnh Quyết Nguyễn不得不说的。尽管在他的解决方案中不需要parallel,因为ClassDetails 的数量会相当少。
【解决方案2】:

代码慢来自于数据库访问。

首先,您应该索引您的数据库。

其次,如果你的学生数据库不是很高,我建议你一口气搞定:

List<Student> findStudentByClassNameIn(List<String> classNames);

然后将您的学生映射到您的班级。

// Map class name with its student
Map<String, List<Student>> stdMap = listStudents().stream().collect(groupingBy(Student::getClassName), toList());

List<StudentsDetails> allStudentsDetails = allClassDetailsDetails.stream()
        .parallel()
        .map(c -> new StudentDetails(stdMap.get(c.getClassName()))
        .collect(toList());

第三,如果您的学生数据太大而无法一次性获取,则分解以一次获取例如 30 个班级数据。

【讨论】:

    【解决方案3】:

    试试我的图书馆AbacusUtil。它应该比原始问题中的代码快几十倍:

    List<StudentsDetails> allStudentsDetails = StreamEx.of(allClassDetailsDetails).parallel(maxThreadNum) // genernally maxThreadNum = 30 is a good choice.
        .map(c -> new StudentsDetails(c.getClassName(), studentService.getAllStudentsByClass(c.getClassName())))
        .toList();
    

    【讨论】:

      猜你喜欢
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 1970-01-01
      相关资源
      最近更新 更多