How to unwrap StreamEx to a "Plain Old Java Stream"?

1.1k views Asked by At

StreamEx is a powerfull library but at some point I don't need its superpowers anymore.

How could I get rid of StreamEx internal overhead ? Could this pose a problem ?

Ex.

public void process(Path path){
    StreamEx.of(Files.lines(path))
        .groupRuns(...)
        //See below 
        .unwrap()
        //
        .map(...)
        .forEach(...)
}
1

There are 1 answers

0
Tagir Valeev On BEST ANSWER

There's no public API method to "unwrap" the StreamEx stream. This is done on purpose. In general the StreamEx class is compatible with original Stream API, so if you need to pass StreamEx to some code accepting simple Stream, you can do this without any fear.

The overhead of using StreamEx is usually very low: only one or several additional call per stream step (some of which could be eliminated by JIT compiler). This overhead (if not eliminated by JIT) appears only during the stream creation, not during evaluation, thus it does not depend on number of elements in the stream. When the terminal operation occurs, the processing is handed over to the original stream, thus in your example during map and forEach evaluation no StreamEx library code will be running.

The StreamEx overhead might be somewhat significant if you create many simple short streams. For example, if you create the StreamEx instance inside the flatMap. So in this case if performance matters and you don't need specific StreamEx operations for the nested Stream, probably it's a good idea to avoid StreamEx inside the flatMap. Though according to my tests the difference become significant (say, more than 5%) only on very artificial cases.

Note that some StreamEx operations are optimized compared to the Stream API equivalents. For example, StreamEx.toList() is usually faster than Stream.collect(Collectors.toList()). Simple create-map-collect operation like StreamEx.of(persons).map(Person::getName).toList() could work several times faster compared to the persons.stream().map(Person::getName).collect(Collectors.toList()).