我必须迭代超过 130 个数据传输对象,每次都会生成一个要上传到 aws S3 的 json。
由于没有改进,整个过程大约需要90秒。我尝试使用兰巴而不是使用兰巴,两者的结果相同。
for(AbstractDTO dto: dtos) {
try {
processDTO(dealerCode, yearPeriod, monthPeriod, dto);
} catch (FileAlreadyExistsInS3Exception e) {
failedToUploadDTOs.add(e.getLocalizedMessage() + ": " + dto.fileName() + ".json");
}
}
dtos.stream().forEach(dto -> {
try {
processDTO(dealerCode, yearPeriod, monthPeriod, dto);
} catch (FileAlreadyExistsInS3Exception e) {
failedToUploadDTOs.add(e.getLocalizedMessage() + ": " + dto.fileName() + ".json");
}
});
经过一些调查,我得出结论,processDTO 方法每个项目大约需要0.650ms才能运行。
我的第一次尝试是使用并行流,结果非常好,大约需要15秒才能完成整个过程:
dtos.parallelStream().forEach(dto -> {
try {
processDTO(dealerCode, yearPeriod, monthPeriod, dto);
} catch (FileAlreadyExistsInS3Exception e) {
failedToUploadDTOs.add(e.getLocalizedMessage() + ": " + dto.fileName() + ".json");
}
});
但我仍然需要减少这段时间。我研究了如何改进并行流,并发现了分叉池技巧:
ForkJoinPool forkJoinPool = new ForkJoinPool(PARALLELISM_NUMBER);
forkJoinPool.submit(() ->
dtos.parallelStream().forEach(dto -> {
try {
processDTO(dealerCode, yearPeriod, monthPeriod, dto);
} catch (FileAlreadyExistsInS3Exception e) {
failedToUploadDTOs.add(e.getLocalizedMessage() + ": " + dto.fileName() + ".json");
}
})).get();
forkJoinPool.shutdown();
不幸的是,结果对我来说有点令人困惑。
当PARALLELISM_NUMBER为8时,完成整个过程大约需要13秒。没有太大的改进。
当PARALLELISM_NUMBER为16时,完成整个过程大约需要8秒钟。
当PARALLELISM_NUMBER为32时,完成整个过程大约需要5秒钟。
所有测试都是使用 postman 请求完成的,调用控制器方法,最终将迭代 130 个项目
我对5秒感到满意,使用32秒作为PARALLELISM_NUMBER,但我担心后果。
保留32可以吗?
理想的PARALLELISM_NUMBER是什么?
在决定其价值时,我必须记住什么?
回首忆惘然
相关分类