gpt4 book ai didi

java - 串行流的性能、内部工作和执行顺序

转载 作者:行者123 更新时间:2023-11-30 06:40:02 25 4
gpt4 key购买 nike

我不认为添加流只是为了通过函数式编程来增加代码的可读性。

如果我在流上执行多个操作,它们是如何在内部计算的。

  1. 在应用多个 map 函数的情况下如何计算 map 函数。一次一个元素或一个完整流上的映射操作,然后是另一个。

  2. 在性能方面,它与对集合执行的正常迭代有何不同。

  3. 在谈到非并行流时,元素的计算顺序是否仅取决于输入集合的类型(即,对于 list、linkedHashmap、sortedset 和 hashSet 等,是有序的)。

  4. 我能否深入了解流的内部工作原理,以便更好地决定何时不建议使用流以及何时建议使用流。(需要检查的因素例如集合大小、序列性质等,)

  5. 我知道字节码是以 .class 的形式为每个类创建的。如何为流操作内部使用的所有 lambda 函数创建字节码。


    List<Integer> ee = new ArrayList<Integer>();
Function<? super Integer, ? extends Integer> f1 = x -> x * 2;
Function<? super Integer, ? extends Integer> f2 = x -> x * x;
Function<? super Integer, ? extends Integer> f3 = x -> x / 2;

ee.stream().map(f1).map(f2).map(f3).collect(Collectors.toList());

最佳答案

  1. 当前的 Stream API 实现在没有中间缓冲的情况下一个接一个地处理元素,除非必须这样做。对于顺序流只有 sorted() 操作是一个“完全屏障”操作,所以对于 map(f1).sorted().map(f2) f1 将应用于整个流,然后对结果进行排序,f2 将应用于每个结果项。在其他情况下,包括相邻的 map(f1).map(f2) f1f2 函数将同时应用于第一个元素,然后两者都用于第二个元素,依此类推。

  2. 可能会更快也可能会更慢,这在很大程度上取决于许多因素,包括您使用的是哪些操作、哪个集合是您的流源、您有多少输入元素以及您如何收集结果。

  3. 在当前实现中 - 是的。虽然没有指定。该规范要求整个流中使用的大部分函数(例如传递给 map 的函数)为 stateless ,所以如果你的程序行为依赖于 lambdas 执行顺序,你很可能违反了指定的契约。

  4. 最重要的因素是代码的清晰度。如果使用流 API 使代码更易于阅读,则可能可以使用它。如果您清楚地看到您的 Stream 是一个性能瓶颈,您可以尝试摆脱它。然而,这在实践中很少发生。我倾向于避免创建许多非常短的流,因为它们会产生垃圾,所以许多短流意味着每个处理的元素有很多垃圾。然而,这在实践中并不总是很重要。

  5. Lambda 被编译为在类体内分离合成方法,并在运行时扩展为实现相应功能接口(interface)并调用该合成方法的匿名类。这是使用 invokedynamic 字节码指令和引导工厂完成的(请参阅标准库中的 java.lang.invoke.LambdaMetafactory 类)。如果您的 lambda 不捕获任何内容,则运行时表示将是单例。否则,每次都会创建该匿名类的一个新实例。

关于java - 串行流的性能、内部工作和执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58967440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com