如何将 StreamEx 解包为 "Plain Old Java Stream"?
How to unwrap StreamEx to a "Plain Old Java Stream"?
StreamEx 是一个强大的库,但在某些时候我不再需要它的超能力了。
我怎样才能摆脱 StreamEx 内部开销?这会带来问题吗?
例如
public void process(Path path){
StreamEx.of(Files.lines(path))
.groupRuns(...)
//See below
.unwrap()
//
.map(...)
.forEach(...)
}
"unwrap" StreamEx
流没有 public API 方法。这是故意的。通常 StreamEx
class 与原始 Stream
API 兼容,因此如果您需要将 StreamEx
传递给某些接受简单 Stream
的代码,你可以毫无恐惧地做到这一点。
使用 StreamEx
的开销通常很低:每个流步骤只有一个或几个额外的调用(其中一些可以被 JIT 编译器消除)。此开销(如果未被 JIT 消除)仅出现在流创建期间,而不出现在评估期间,因此它不依赖于流中元素的数量。当终端操作发生时,处理被移交给原始流,因此在 map
和 forEach
评估期间的示例中,没有 StreamEx 库代码将是 运行.
如果您创建许多简单的短流,StreamEx
开销可能会有些显着。例如,如果您在 flatMap
中创建 StreamEx
实例。因此,在这种情况下,如果性能很重要并且您不需要对嵌套 Stream
进行特定的 StreamEx
操作,那么避免 flatMap
内部的 StreamEx
可能是个好主意。尽管根据我的测试,差异仅在非常人为的情况下才会变得显着(比如超过 5%)。
请注意,与 Stream API 等价物相比,一些 StreamEx
操作已经过优化。例如,StreamEx.toList()
通常比 Stream.collect(Collectors.toList())
快。与 persons.stream().map(Person::getName).collect(Collectors.toList())
.
相比,像 StreamEx.of(persons).map(Person::getName).toList()
这样简单的 create-map-collect 操作可以快几倍
StreamEx 是一个强大的库,但在某些时候我不再需要它的超能力了。
我怎样才能摆脱 StreamEx 内部开销?这会带来问题吗?
例如
public void process(Path path){
StreamEx.of(Files.lines(path))
.groupRuns(...)
//See below
.unwrap()
//
.map(...)
.forEach(...)
}
"unwrap" StreamEx
流没有 public API 方法。这是故意的。通常 StreamEx
class 与原始 Stream
API 兼容,因此如果您需要将 StreamEx
传递给某些接受简单 Stream
的代码,你可以毫无恐惧地做到这一点。
使用 StreamEx
的开销通常很低:每个流步骤只有一个或几个额外的调用(其中一些可以被 JIT 编译器消除)。此开销(如果未被 JIT 消除)仅出现在流创建期间,而不出现在评估期间,因此它不依赖于流中元素的数量。当终端操作发生时,处理被移交给原始流,因此在 map
和 forEach
评估期间的示例中,没有 StreamEx 库代码将是 运行.
如果您创建许多简单的短流,StreamEx
开销可能会有些显着。例如,如果您在 flatMap
中创建 StreamEx
实例。因此,在这种情况下,如果性能很重要并且您不需要对嵌套 Stream
进行特定的 StreamEx
操作,那么避免 flatMap
内部的 StreamEx
可能是个好主意。尽管根据我的测试,差异仅在非常人为的情况下才会变得显着(比如超过 5%)。
请注意,与 Stream API 等价物相比,一些 StreamEx
操作已经过优化。例如,StreamEx.toList()
通常比 Stream.collect(Collectors.toList())
快。与 persons.stream().map(Person::getName).collect(Collectors.toList())
.
StreamEx.of(persons).map(Person::getName).toList()
这样简单的 create-map-collect 操作可以快几倍