[concurrency-interest] jsr166y Parallel*Array withMapping/withFilter chaining

Doug Lea dl at cs.oswego.edu
Wed Jan 23 16:45:00 EST 2008

David J. Biesack wrote:
> I find that I cannot do the following
>    public ParallelDoubleArray chain(int size) {
>         return = ParallelDoubleArray.create(size, myForkJoinExecutor)
>          .replaceWithGeneratedValue(myGenerator)
>          .withMapping(myMapping)
>          .withFilter(myFilter)
>          .withMapping(myOtherMapping).all();
>     }

I've been waiting to get reaction on this. We now have two complaints
about it (you and Kasper Nielsen), so it might be worth reconsidering.

The current internal support is set up to allow at most one
(parallel) selection per expression, which
I think is a good rule because it provides an understandable
(and efficient) performance model -- it doesn't secretly require
multiple temporary workspaces or multiple per-element evaluations of
mapping functions. Bear in mind that fast parallel filtering is
inherently a two-phase operation (sometimes with internal pipelined
overlap): Find indices of all matching elements,
and then when you know how many there are, create and put them in new array.
(That's one downside of arrays as opposed to other data structures --
you need to know size before you can create.)

Note that the above case differs in that the all() call must evaluate
mappings, and then put elements somewhere to collect into
returned array in case they pass filter. It is possible to either do
slower filtering to avoid multiple calls to mapping functions
that would otherwise be needed in this case, or to create extra
internal workspace to hold evaluated elements. But in keeping
with desire for simple performance model, since there are two options
I cruelly make you be explicit about it. To get the evaluate-and-store
version, use all(). To do the slower-filter version, rewrite the
filter so that it internally does the mapping needed to decide
whether to keep the element.

There might be a good always-acceptable approach for this case
though, which would make for a better argument for allowing it.
I'll explore the possibilities.

Further complicating this story is that if all you want is a reduction,
then these concerns don't even apply, and we might as well
support it, but doing this leads to an even less regular API,
so it is currently out just on those grounds.


More information about the Concurrency-interest mailing list