Java8 - 在不收集性能的情况下使用流进行映射

Java8 - Mapping with Streams without Collecting for Performance

呈指数级增长的流

我有一个 Stream 指数增长 用于创建排列。因此每次调用 addWeeks 都会增加 Stream.

中的元素数量
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 

问题

问题

更新:

感谢大家的帮助!

我已经把方法的代码放在 gist

感谢@Holger 和@lexicore 建议 return 在 addWeeks 中使用 Stream<SeasonBuilder>。正如@lexicore

预测的那样,性能略有提高

我尝试使用 parallelStream(),性能没有显着变化

上下文

我正在创建 Fantasy Football 赛季的所有可能排列,这些排列将在其他地方用于统计分析。在 4 支球队、14 周的赛季中,对于任何给定的一周,都可能存在三种不同的可能性

为了解决这个问题,插入排列,我们就有了所有可能的季节。完毕!但是等等……如果 Team 1 只与 Team 2 比赛怎么办?那么其他球队会很难过。所以对排列有一些限制。

每支球队之间的比赛次数必须大致相同(即 1 队不能在一个赛季中与 3 队比赛 10 次)。在此示例中 - 4 支球队,14 周 - 每支球队最多与另一支球队比赛 5 次。所以在创建排列时必须进行某种过滤,以避免无效的季节。

这变得更有趣的地方是:

我正在尝试尽可能优化性能,因为有很多排列要创建。考虑到限制条件,一个 4 支球队、14 周的赛季会创造 756 756(=14!/(5!5!4!))个可能的赛季。 6 队或 8 队赛季变得更加疯狂。

你的整个结构从一开始就很可疑。如果您对性能感兴趣,那么显式生成所有排列不太可能是一种好方法。

我也不认为收集设置和再次流式传输是性能问题。

但是,还是要回答你的问题:你为什么不直接从addWeeksreturnStream<SeasonBuilder>,你为什么先收集它来设置? Return 流目录,不收集:

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
}

那么你就不需要 map/flatMap,一个 flatMap:

sbStream = sbStream.flatMap(sb -> sb.addWeeks(possibleWeeks));

但这对你的表现没有多大帮助。