Should we allow use Unsafe or ByteArrayLittleEndian for trivial byte[] writes in core-libs?
温绍锦(高铁)
shaojin.wensj at alibaba-inc.com
Sun Oct 8 06:52:13 UTC 2023
Should we allow use Unsafe or ByteArrayLittleEndian for trivial byte[] writes in core-libs?
There is already code that uses ByteArrayLittleEndian to improve performance, such as:
```java
package java.util;
class UUID {
public String toString() {
// ...
ByteArrayLittleEndian.setInt(
buf,
9,
HexDigits.packDigits(((int) msb) >> 24, ((int) msb) >> 16));
// ...
}
}
```
There are examples of using ByteArrayLittleEndian and then removing it because it caused the JVM to start slowly (we can use Unsafe.putShortUnaligned to solve the problem of slow JVM startup)
```java
package java.lang;
class StringLatin1 {
private static void writeDigitPair(byte[] buf, int charPos, int value) {
short pair = DecimalDigits.digitPair(value);
// UNSAFE.putShortUnaligned(buf, ARRAY_BYTE_BASE_OFFSET + charPos, pair);
buf[charPos] = (byte)(pair);
buf[charPos + 1] = (byte)(pair >> 8);
}
}
```
Here is an example in the PR Review is disagreeing with the use of ByteArrayLittleEndian
https://github.com/openjdk/jdk/pull/15768 <https://github.com/openjdk/jdk/pull/15768 >
```java
package java.util;
class HexFormat {
String formatOptDelimiter(byte[] bytes, int fromIndex, int toIndex) {
// ...
short pair = HexDigits.digitPair(bytes[fromIndex + i], ucase);
int pos = i * 2;
rep[pos] = (byte)pair;
rep[pos + 1] = (byte)(pair >>> 8);
// ByteArrayLittleEndian.setShort(rep, pos, pair);
}
}
```
This is another example of PR Review disagreeing with the use of ByteArrayLittleEndian.
https://github.com/openjdk/jdk/pull/15990 <https://github.com/openjdk/jdk/pull/15990 >
```java
package java.lang;
class AbstractStringBuilder {
static final class Constants {
static final int NULL_LATIN1;
static final int NULL_UTF16;
static {
byte[] bytes4 = new byte[] {'t', 'r', 'u', 'e'};
byte[] bytes8 = new byte[8];
NULL_LATIN1 = ByteArrayLittleEndian.getInt(bytes4, 0);
StringLatin1.inflate(bytes4, 0, bytes8, 0, 4);
NULL_UTF16 = ByteArrayLittleEndian.getLong(bytes8, 0);
}
}
private AbstractStringBuilder appendNull() {
ensureCapacityInternal(count + 4);
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
ByteArrayLittleEndian.setInt(val, count, Constants.NULL_LATIN1);
} else {
ByteArrayLittleEndian.setLong(val, count << 1, Constants.NULL_UTF16);
}
this.count = count + 4;
return this;
}
}
```
In these examples, using Unsafe/ByteArrayLittleEndian significantly improves performance. If JIT automatic optimization is the best solution, but SuperWord Level Parallelism (SLP) does not currently support this optimization, what are our recommendations? What scenarios cannot use Unsafe, and what scenarios cannot use ByteArrayLittleEndian?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20231008/dac007c6/attachment.htm>
More information about the core-libs-dev
mailing list