Hi Tagir,

----- Mail original -----
> De: "Tagir Valeev" <amae...@gmail.com>
> À: "Stuart Marks" <stuart.ma...@oracle.com>
> Cc: "core-libs-dev" <core-libs-dev@openjdk.java.net>
> Envoyé: Samedi 16 Juin 2018 06:01:35
> Objet: Re: RFR(s): 8060192: Add default method Collection.toArray(generator)

> Hello!
> 
> If you are going to create long-living array which is likely to be empty,
> it's good to deduplicate them to spare the heap space. This can be easily
> done via existing toArray method like
> collection.toArray(MyClass.EMPTY_ARRAY) assuming we have an empty array
> constant. We use this pattern very often in IntelliJ IDEA source code (e.
> g. think of method which returns an array of Java member annotations; often
> there are none). New generator methods is much less convenient for this:
> toArray(s -> s == 0?MyClass.EMPTY_ARRAY:new MyClass[s]). I'm actually
> missing a method accepting an empty array instead of generator in the
> Stream API. And I don't think that new collection method is useful. The
> existing one is perfect.
> 
> With best regards,
> Tagir Valeev

we can expect the VM to not allocate the array if once inlined the code is
  new MyClass[0].getClass()

if it's not the case, i think it's a better idea to tweak the VM rather than 
try to change an API based on a pattern that should not be necessary.

Rémi

> 
> пт, 15 июня 2018 г., 8:03 Stuart Marks <stuart.ma...@oracle.com>:
> 
>> Hi all,
>>
>> I wanted to restart review of the changeset for bug JDK-8060192 [1]. The
>> latest
>> webrev is here: [2].
>>
>> The previous review was from December 2017: [3]. The only difference
>> between the
>> current changeset and the previous one is the removal of the overriding
>> implementations (see explanation below). Much of the discussion in the
>> previous
>> review thread was around performance and the shape of the API.
>>
>> # Performance
>>
>> I previously had done some benchmarking on this and reported the results:
>> [4].
>> (I've recently re-done the benchmarks and conclusions are essentially the
>> same.)
>>
>> The upshot is that implementations that use Arrays.copyOf() are the
>> fastest,
>> probably because it's an intrinsic. It can avoid zero-filling the freshly
>> allocated array because it knows the entire array contents will be
>> overwritten.
>> This is true regardless of what the public API looks like. The default
>> implementation calls generator.apply(0) to get a zero-length array and
>> then
>> simply calls toArray(T[]). This goes through the Arrays.copyOf() fast
>> path, so
>> it's essentially the same speed as toArray(new T[0]).
>>
>> The overrides I had previously provided in specific implementation classes
>> like
>> ArrayList actually are slower, because the allocation of the array is done
>> separately from filling it. This necessitates the extra zero-filling step.
>> Thus,
>> I've removed the overrides.
>>
>> # API Shape
>>
>> There was some discussion about whether it would be preferable to have a
>> Class
>> parameter as a type token for the array component type or the array type
>> itself,
>> instead of using an IntFunction generator. Most of this boils down to what
>> people are comfortable with. However, there are a few points that make the
>> generator function approach preferable.
>>
>> One point in favor of using a generator is that Stream already has a
>> similar
>> toArray(generator) method.
>>
>> Comparing this to the type token alternatives, for simple tasks like
>> converting
>> Collection<String> to String[], things are about equal:
>>
>>      toArray(String[]::new)
>>      toArray(String.class)
>>      toArray(String[].class)
>>
>> However, things are hairier if the element type of the collection is
>> generic,
>> such as Collection<List<String>>. The result type is a generic array
>> List<String>[]. Using class literals or array constructor references will
>> necessitate using an unchecked cast, because none of these can be used to
>> represent a generic type.
>>
>> However, it's possible to use a method reference to provide a properly
>> generic
>> IntFunction. This would enable the toArray(generator) method to be used
>> without
>> any unchecked casts. (The method it refers to might need have an unchecked
>> cast
>> within it, though.) Such a method could also be reused for the
>> corresponding
>> Stream.toArray(generator) method.
>>
>> For these reasons I'd like to proceed with adding toArray(generator) API.
>>
>> Thanks,
>>
>> s'marks
>>
>>
>> [1] https://bugs.openjdk.java.net/browse/JDK-8060192
>>
>> [2] http://cr.openjdk.java.net/~smarks/reviews/8060192/webrev.3/
>>
>> [3]
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050325.html
>>
>> [4]
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050585.html
>>

Reply via email to