Java Streams:收集长数据流的复杂度是否与基于Set::contains过滤相同?



我有一个应用程序,它接受员工id作为用户输入,然后过滤匹配id的员工列表。用户输入应该是3-4个id,员工列表是几千。

基于性能考虑,我提出了以下两种使用流过滤器的方法。

Method1

这里的动机不是为每个员工运行过滤器,而是在请求的id列表上运行它,保证非常短。

private static Set<Long> identifyEmployees(CustomRequest request)
List<Long> requestedIds = request.getRequestedIDs();                            
if (!requestedIds.isEmpty()) {
Set<Long> allEmployeeIds = 
employeeInfoProvider
.getEmployeeInfoList()  // returns List<EmployeeInfo>
.stream()
.map(EmployeeInfo::getEmpId)  // getEmpId() returns a Long
.collect(Collectors.toSet());
return requestedIds.stream().filter(allEmployeeIds::contains).collect(Collectors.toSet());         
}
return Collections.emptySet();
}

Method2

这里的动机是用过滤器替换Method1中的collect(),因为复杂性是相同的。这里的Collect()实际上会在非常少的元素上运行。

private static Set<Long> identifyEmployees(CustomRequest request)
Set<Long> requestedIds = request.getRequestedIDs()   // returns List<Long>
.stream()
.collect(Collectors.toSet());
if (!requestedIds.isEmpty()) {
return employeeInfoProvider
.getEmployeeInfoList()  // returns List<EmployeeInfo>
.stream()
.map(EmployeeInfo::getEmpId)  // getEmpId() returns a Long
.filter(requestedIds::contains)
.collect(Collectors.toSet());
}
return Collections.emptySet();
}

Method2的性能和Method1一样好吗?还是Method1表现得更好?

我希望Method2在所有情况下都能表现得一样好或更好。

收集中间集增加了分配开销。它减少了requestedIds::contains调用的数量,如果有很多重复,那么您稍后必须执行,但即使这样,您将每个Set::add调用交换为Set::contains调用,每个调用都应该是一个小的胜利。

一个可能更快(不是更干净)的选项是当所有被请求的id被检测到时立即返回,但我不确定它是否可以用流API实现。

private static Set<Long> identifyEmployees(CustomRequest request) {
Set<Long> requestedIds = request.getRequestedIDs()   // returns List<Long>
.stream()
.collect(Collectors.toSet());
Set<Long> result = new HashSet<>();
if (!requestedIds.isEmpty()) {
Iterator<EmployeeInfo> employees = employeeInfoProvider.getEmployeeInfoList().iterator();
while (result.size() < requestedIds.size() && employees.hasNext()) {
Long employeeId = employees.next().getEmpId();
if (requestedIds.contains(employeeId)) {
result.add(employeeId);
}
}
}
return result;
}

但是,只有当employeeInfoProvider.getEmployeeInfoList()返回具有相同id的雇员的多个副本时才有意义。否则,如上所述,method2是更好的选择。

相关内容

  • 没有找到相关文章

最新更新