Primitive streams and optional (original) (raw)

Remi Forax forax at univ-mlv.fr
Thu Nov 29 10:00:06 PST 2012


On 11/29/2012 04:42 PM, Doug Lea wrote:

On 11/28/12 10:59, Remi Forax wrote:

On 11/28/2012 04:27 PM, Doug Lea wrote:

On 11/26/12 15:43, Brian Goetz wrote:

1. Ban nulls. This is equivalent to adding .tee(e -> { if (e == null) throw new NPE(); } between all stages of a pipeline.

2. Ignore nulls. This is what Doug is proposing, and is equivalent to adding .filter(e -> e != null) between all stages of a pipeline. 3. Tolerate nulls. This treat nulls as "just another value" and hopes that lambdas and downstream stages can deal. (They do vary a little: #3 will sometimes be the most expensive, since the lack of a pre-null-check forces twistier code paths to be generated later on first dereference of a field.) Yes, for #3, if someone call any stream pipelines without sending null, it's ok. If there is just one codepath that sends one null through one pipeline, the user will pay a high tax once because the VM may have to deoptimize a lot of pipeline codes (not just the code of one pipeline). Mostly an aside: Hoisting various null checks (including especially whether the supplied lambdas are null) in the specialized CHM FJ tasks gives a consistent 5% speedup. 5% is not huge, but for a heavily used core library class, it's worth the effort. For some of the task classes, I have more lines of code doing the hoisted null and bounds checks than actual foreach etc code.

I suspect we will have to do the same in serial code too.

The main reason it is effective is that the VM cannot hoist them further because it must unpack from the task objects, which sometimes entails some volatiles/atomics, forcing rereads.

and even before that, if VM is not able to de-virtualize the the lambda call, the JIT can't know if the lambda body change the task field or not.

(Digressing further: A paper at Splash last month showed that you could avoid this in most cases by using stack frames for task closures and using exception mechanics for dealing with steals and stolen tasks. This would require major surgery on JVMs though.)

Maybe not, I haven't read the Splash paper but you can simulate stack allocation of objects using coroutines, but may be the cost of coroutine switch is bigger than the gain of de-structuring the object to store the fields on stack.

-Doug

Rémi



More information about the lambda-libs-spec-observers mailing list