Java8-使用流进行映射而不收集性能 指数增长流
我有一个Java8-使用流进行映射而不收集性能 指数增长流,java,lambda,java-8,java-stream,collectors,Java,Lambda,Java 8,Java Stream,Collectors,我有一个流,它以指数方式增长,用于创建置换。因此,每次调用addWeeks都会增加流中的元素数 Stream<SeasonBuilder> sbStream = sbSet.stream(); for (int i = 1; i <= someCutOff; i++) { sbStream = sbStream.map(sb -> sb.addWeeks(possibleWeeks)) .flatMap(Collec
流
,它以指数方式增长,用于创建置换。因此,每次调用addWeeks
都会增加流中的元素数
Stream<SeasonBuilder> sbStream = sbSet.stream();
for (int i = 1; i <= someCutOff; i++) {
sbStream = sbStream.map(sb -> sb.addWeeks(possibleWeeks))
.flatMap(Collection::stream);
}
// Collect SeasonBuilders into a Set
return sbStream.collect(Collectors.toSet()); // size > 750 000
内存不足错误。。。。。如果可能,周的大小为15
问题
- 我应该使用方法链而不是
map
,然后是flatmap
- 如何修改
addWeeks
,使我不必将所有内容收集到集合中
?
- 我是否应该返回
流
?我可以flatmap
aStream
吗
更新:
谢谢大家的帮助
我已经将这些方法的代码放在
感谢@Holger和@lexicore建议在addWeeks
中返回流
。正如@lexicore所预测的,性能略有提高
我尝试使用parallelStream()
,但性能没有明显变化
上下文
我正在创建一个赛季的所有可能的排列,这些排列将在其他地方用于统计分析。在一个4队14周的赛季中,对于任何给定的一周,可能有三种不同的可能性
- (1对2),(3对4)
- (1对3),(2对4)
- (1对4),(2对3)
为了解决这个问题,插入排列,我们就有了所有可能的季节。完成!但是等等。。。如果第一队只和第二队比赛呢。然后其他球队会很伤心。所以在排列上有一些限制
每支球队之间的比赛次数必须大致相同(即1队不能在一个赛季内与3队比赛10次)。在这个例子中——4个队,14周——每个队最多与另一队比赛5次。因此,在创建排列时必须进行某种过滤,以避免无效的季节
更有趣的是:
- 6个团队联盟——15个可能的星期
- 8队联赛——105周
- 10支球队联盟——945个可能的星期
我正在尽可能优化性能,因为有很多排列需要创建。考虑到限制因素,一个4队14周的赛季创造了756756个可能的赛季。6队或8队赛季变得更加疯狂。你的整个结构一开始就非常可疑。如果您对性能感兴趣,那么显式生成所有置换不太可能是一种好方法
我也不认为再次收集设置和流媒体是性能问题
但是,为了回答您的问题:为什么不直接从addWeeks
返回Stream
,为什么要先收集它?直接返回流,不收集:
public Stream<SeasonBuilder> addWeeks(
final Set<Set<ImmutablePair<Integer, Integer>>> possibleWeeks) {
return possibleWeeks.stream()
.filter(containsMatchup()) // Finds the weeks to add
.map(this::addWeek); // Create new SeasonBuilders with the new week
}
但这对你的表现没有多大帮助。那么你想实现什么呢?如果你想要一个快速的东西,生成所有排列很可能不是最好的开始方法。很明显,你必须如何更改addWeeks
?让它返回元素的流
,而不是集
(并将名称更改为反映其实际功能的名称,因为它显然不添加…
)。除非你想重新设计一切,包括你在问题中没有提到的东西,否则这是唯一可能的改变。无论您是使用map
,然后是flatMap
,还是使用单个flatMap
,都是无关紧要的。@alexdriedger将任何>750_000个元素收集到任何数据结构都会很慢,添加排列只会让事情变得更糟。霍尔格是对的,除非你用简单的语言解释你想要达到的目标,否则很难给出任何建议。@霍尔格,你介意回答这个问题吗?我认为,当你实例化你的流时,激活并行流将是一个很好的促进。尝试一下,并给我反馈。你是正确的,再次收集和流媒体不是主要的性能问题。我根据你的建议再次运行了它,它的性能略有提高
public Stream<SeasonBuilder> addWeeks(
final Set<Set<ImmutablePair<Integer, Integer>>> possibleWeeks) {
return possibleWeeks.stream()
.filter(containsMatchup()) // Finds the weeks to add
.map(this::addWeek); // Create new SeasonBuilders with the new week
}
sbStream = sbStream.flatMap(sb -> sb.addWeeks(possibleWeeks));