Spliterator flags as enum (was Initial java.util.Spliterator putback)
Talden
talden at gmail.com
Fri Mar 29 20:54:38 PDT 2013
It should be possible to document the representation of options being
exposed in a class (either as a Set or as an int) without defining the
options themselves as structurally unrelated static final int fields.
Can we not define the Spliterator.Options as an enum with a bit-value per
enum element?
EG (hastily mocked up)
// Assuming this is a nested enum within Spliterator due the tight coupling.
enum Option {
ORDERED(1), ...;
public final int bit;
Option(final int bit) { this.flag = bit; }
public static Option asOption(final int bit) { ... }
public static Set<Option> asSet(final int bits) { ... }
public static Stream<Option> asStream(final int bits) { ... }
public static int asBits(final StreamFlag... options) { ... }
public static String toString(final int bits) { ... }
}
Then you can choose to expose options on the stream as both an int and a
set (the internal representation being an int) and document that fact as
the performant choice - indeed you could document the Set representation as
being immutable and disconnected so that it's clear that to modify the
flags you do bit manipulation.
The static methods provide the convenient and documented interchange
between representations and there's now a clearly defined way (and
reflection supporting naming) to process the possible option values.
I'm assuming here that any differences in calling code will largely
optimise away for the existing low-level machinery that can continue to use
the int representation but reference the enum in javadoc.
--
Aaron Scott-Boddendijk
On Fri, Mar 29, 2013 at 5:39 PM, Paul Benedict <pbenedict at apache.org> wrote:
> I think the use of EnumSet in a public API is superior to bit flags.
> Worrying about the number of bytes here is not important since they will
> all end up being garbage collected when the stream processing ends.
>
>
> On Thu, Mar 28, 2013 at 6:56 PM, Vitaly Davidovich <vitalyd at gmail.com
> >wrote:
>
> > Enum and EnumSet *are* good, but the problem is the overhead of
> > representation. If all you want is 32 bits to play with, you pay
> exactly 4
> > bytes in price if using int. With EnumSet, you pay object/heap overhead
> -
> > on x64, 4 bytes vs 24; you pay GC price if you have lots of objects with
> > embedded EnumSet instances in them, there's indirection in
> loading/passing
> > them, etc
> >
> > Until JVM supports/implements value type/structure semantics, the
> overhead
> > for these types of things continues to be an eyebrow raising issue.
> >
> > Sorry Josh, I know this isn't related to Spliterator directly and you did
> > say that bit fields are *usually* not a good idea, but just wanted to
> throw
> > this out there as more a plea for Oracle to do something about
> struct/value
> > type hole. :)
> >
> > Sent from my phone
> > On Mar 28, 2013 3:38 PM, "Joshua Bloch" <josh at bloch.us> wrote:
> >
> > > Doug,
> > >
> > > On Thu, Mar 28, 2013 at 12:06 PM, Doug Lea <dl at cs.oswego.edu> wrote:
> > >
> > > > On 03/28/13 14:52, Joshua Bloch wrote:
> > > >
> > > >> Doug,
> > > >>
> > > >> I don't get it. You can set and unset flags on your own EnumSet.
> Why
> > > >> isn't that
> > > >> sufficient?
> > > >>
> > > >
> > > > There are a lot of problems. First, even
> > > > though most spliterators will return the same set of
> > > > characteristics each time, you can't just create one static one:
> > > >
> > > > class MySpliterator { ...
> > > > static final EnumSet<Characteristics> cs = EnumSet.of(...);
> > > > EnumSet<Characteristics> characteristics() return cs; }
> > > > }
> > > >
> > > > ... because you cannot risk that no one will modify.
> > > >
> > >
> > > Sounds like a perfect opportunity to put in immutableEnumSet, which is
> > > trivial to implement and generally useful. Alternatively, don't share,
> > and
> > > see if the performance it good enough. (I suspect it will be.)
> > >
> > > Second, when inside streams, you'd have to create a new EnumSet
> > > > Object across each stage, that somehow secretly extends the
> > > > public Characteristics with non-public internal control flags.
> > > > Which means either some slow conversion table or grabbing
> > > > private EnumSet internals.
> > > >
> > >
> > > Or having two EnumSets: one public, consisting of public constants, and
> > one
> > > private, consisting of private constants. Again, doesn't sound like a
> big
> > > deal.
> > >
> > > So it is both slow and painful.
> > >
> > >
> > > You haven't convinced me of either (yet). Did you measure the
> > performance?
> > >
> > >
> > > > I tried to make it less so,
> > > > knowing that people sometimes react hostilely to plain bit
> > > > sets. But I'm sure that the current scheme is better than all
> > > > I tried. (Ditto for Brian Goetz and Paul Sandoz).
> > > > In fact, I think the current scheme is sorta nice in
> > > > an absolute sense.
> > >
> > >
> > > Could be. I haven't seen it. That said, I find that bit fields are
> > usually
> > > not a good idea in the post-enum age.
> > >
> > > Josh
> > >
> > >
> >
> >
>
>
More information about the lambda-dev
mailing list