On Sun, 11 Oct 2026 19:17:30 GMT, Liam Miller-Cushon <[email protected]> wrote:
>> This change adds Vector API methods that load the code units of a >> `java.lang.String` into a vector without copying, to allow processing a >> `String` with a vector loop instead of a scalar loop over `charAt`. >> >> As discussed in the [panama-dev@ thread 'String processing and Vector >> APIs'](https://mail.openjdk.org/archives/list/[email protected]/thread/YSPX3TBXZTZEFZNXWDYOZCWLUQPC62P6/), >> one motivating use-case is a regex library that wants to accelerate scans >> for character classes. Implementing these methods outside the JDK using >> scalar `charAt` loops is slower than a vectorized implementation. >> >> ### Goals >> >> * Performance - to get the full performance benefit, these APIs should avoid >> copies or re-encoding, since a copy or re-encoding would be O(n) and reduce >> the performance benefit of a vector loop >> * Encapsulation - encapsulation of `java.lang.String` internals must be >> preserved, including preventing modification of the String's backing >> storage, and also preserving encapsulation of String implementation details >> (like the exact encoding under Compact Strings) >> >> ### Design >> >> >> // ByteVector >> static boolean compatibleWith(String string, Charset charset) >> static ByteVector fromString(VectorSpecies<Byte> species, String string, >> Charset charset, int offset) >> static ByteVector fromString(VectorSpecies<Byte> species, String string, >> Charset charset, int offset, VectorMask<Byte> m) >> >> // ShortVector >> static boolean compatibleWith(String string, Charset charset) >> static ShortVector fromString(VectorSpecies<Short> species, String string, >> Charset charset, int offset) >> static ShortVector fromString(VectorSpecies<Short> species, String string, >> Charset charset, int offset, VectorMask<Short> m) >> >> >> `compatibleWith` runs in constant time. If it returns `true`, `fromString` >> loads the String's backing storage without a copy, if it returns false >> `fromString` will throw `IllegalArgumentException` and callers are expected >> to handle falling back to a scalar loop. >> >> >> if (ByteVector.compatibleWith(s, ISO_8859_1)) { >> // ... >> } else if (ShortVector.compatibleWith(s, UTF_16)) { >> // ... >> } else { >> // scalar fallback >> } >> >> >> These methods deal with strings in terms of code units, not encoded bytes. >> `ShortVector.fromString` loads the String's UTF-16 code units in native byte >> order without a BOM and any unpaired surrogates preserved, providing the >> same values as a scalar loop over `charAt`. Guaranteeing a well-formed >> encoding would... > > Liam Miller-Cushon has updated the pull request with a new target base due to > a merge or a rebase. The incremental webrev excludes the unrelated changes > brought in by the merge/rebase. The pull request contains 13 additional > commits since the last revision: > > - Clean up unused import > - Merge remote-tracking branch 'origin/master' into short-vector > - Move asReadOnlyMemorySegment to String > - Add a benchmark > > Also adjust javadoc, convert test to JUnit 5, other small adjustments > - javadoc > - Move access to jdk.internal.foreign.StringSupport > - Make test inputs longer > - Test coverage > - Move to X-Vector.java.template, update javadoc, add masked overloads > - ShortVector.compatibleWith > - ... and 3 more: https://git.openjdk.org/jdk/compare/f01b6938...1c6ff6ab src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java line 3812: > 3810: * {@link ByteVector#fromString(VectorSpecies, String, Charset, > int)}. > 3811: * > 3812: * @param string the string In some FFM methods we used these descriptions: * @param str the Java string to be converted into a C string * @param charset the charset used to {@linkplain Charset#newEncoder() encode} the * string bytes They can use some tweaks of course (esp. first), like: * the Java string to be encoded and loaded into a `ByteVector` * the charset used to {@linkplain Charset#newEncoder() encode} the string bytes ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/32373#discussion_r4270318606
