RFR: 8305774: String.join(CharSequence, Iterable) can be optimized if Iterable is a Collection [v3]

ExE Boss duke at openjdk.org
Mon Apr 10 17:40:45 UTC 2023


On Mon, 10 Apr 2023 17:05:28 GMT, jmehrens <duke at openjdk.org> wrote:

>> src/java.base/share/classes/java/lang/String.java line 3466:
>> 
>>> 3464:         }
>>> 3465:         int size = 0;
>>> 3466:         for (CharSequence cs: elements) {
>> 
>> I would think you have to locally store the result of `elements.spliterator()` and then use Spliterators::iterator to adapt it back to an iterator.  This should correctly handle [early-binding](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Spliterator.html#binding) spliterators.
>> 
>> I think in the loop the code should use ArraysSupport.newLength.
>
> That if/else looks like a job for Math.clamp.  Something like:
> 
> var si = element.spliterator();
> String[] elems = new String[Math.clamp(si.estimateSize(), 8, ArraysSupport.SOFT_MAX_ARRAY_LENGTH)];
> 
> 
> Perhaps we need to pad the estimate a little bit to try and avoid one resize:
> 
> var si = element.spliterator();
> String[] elems = new String[Math.clamp(si.estimateSize() + 8L, 8, ArraysSupport.SOFT_MAX_ARRAY_LENGTH)];

Note that this also has to handle the case where `si.estimateSize()` returns values close to `Long.MAX_VALUE`:

final var si = elements.spliterator();
final long est = si.estimateSize();
final int length;

final long MIN_LENGTH = 8;
if ((si.hasCharacteristics() & Spliterator.SIZED) != 0) {
	length = (int) Math.clamp(est, MIN_LENGTH, ArraysSupport.SOFT_MAX_ARRAY_LENGTH);
} else if (est == Long.MAX_VALUE) {
	length = MIN_LENGTH;
} else if (est >= ArraysSupport.SOFT_MAX_ARRAY_LENGTH - MIN_LENGTH) {
	length = ArraysSupport.SOFT_MAX_ARRAY_LENGTH;
} else {
	length = (int) Math.clamp(est + MIN_LENGTH, MIN_LENGTH, ArraysSupport.SOFT_MAX_ARRAY_LENGTH);
}

var elems = new String[length];

int size = 0;
for (final var it = Spliterators.iterator(si); it.hasNext();) {
	CharSequence cs = it.next();

// rest of method...

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/13383#discussion_r1161920643


More information about the core-libs-dev mailing list