mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-23 21:30:26 +00:00
optimize toHexString
This commit is contained in:
parent
91db7c0877
commit
79fe74eb8f
@ -286,7 +286,55 @@ public final class Integer extends Number
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public static String toHexString(int i) {
|
||||
return toUnsignedString0(i, 4);
|
||||
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(i);
|
||||
int len = Math.max(((mag + 3) / 4), 1);
|
||||
byte coder = COMPACT_STRINGS ? LATIN1 : UTF16;
|
||||
byte[] chars = new byte[len << coder];
|
||||
long x = hex8(i);
|
||||
do {
|
||||
--len;
|
||||
byte b = (byte) x;
|
||||
if (COMPACT_STRINGS) {
|
||||
StringLatin1.putChar(chars, len, b);
|
||||
} else {
|
||||
StringUTF16.putChar(chars, len, b);
|
||||
}
|
||||
x >>>= 8;
|
||||
} while (len > 0);
|
||||
return new String(chars, coder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the least significant 8 bytes from the input integer i, convert each byte into its corresponding 2-digit
|
||||
* hexadecimal representation, concatenate these hexadecimal strings into one continuous string, and then interpret
|
||||
* this string as a hexadecimal number to form and return a long value.
|
||||
*/
|
||||
static long hex8(long i) {
|
||||
long x = Long.expand(i, 0x0F0F_0F0F_0F0F_0F0FL);
|
||||
/*
|
||||
Use long to simulate vector operations and generate 8 hexadecimal characters at a time.
|
||||
------------
|
||||
0 = 0b0000_0000 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '0'
|
||||
1 = 0b0000_0001 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '1'
|
||||
2 = 0b0000_0010 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '2'
|
||||
3 = 0b0000_0011 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '3'
|
||||
4 = 0b0000_0100 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '4'
|
||||
5 = 0b0000_0101 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '5'
|
||||
6 = 0b0000_0110 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '6'
|
||||
7 = 0b0000_0111 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '7'
|
||||
8 = 0b0000_1000 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '8'
|
||||
9 = 0b0000_1001 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 0 + 0x30 + (i & 0xF) => '9'
|
||||
10 = 0b0000_1010 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'a'
|
||||
11 = 0b0000_1011 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'b'
|
||||
12 = 0b0000_1100 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'c'
|
||||
13 = 0b0000_1101 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'd'
|
||||
14 = 0b0000_1110 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'e'
|
||||
15 = 0b0000_1111 => m = ((i + 6) & 0x10); (m << 1) + (m >> 1) - (m >> 4) => 39 + 0x30 + (i & 0xF) => 'f'
|
||||
*/
|
||||
long m = (x + 0x0606_0606_0606_0606L) & 0x1010_1010_1010_1010L;
|
||||
return ((m << 1) + (m >> 1) - (m >> 4))
|
||||
+ 0x3030_3030_3030_3030L
|
||||
+ (x & 0x0F0F_0F0F_0F0F_0F0FL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -34,6 +34,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import jdk.internal.misc.CDS;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.util.DecimalDigits;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
@ -43,6 +44,7 @@ import static java.lang.Character.digit;
|
||||
import static java.lang.String.COMPACT_STRINGS;
|
||||
import static java.lang.String.LATIN1;
|
||||
import static java.lang.String.UTF16;
|
||||
import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
|
||||
/**
|
||||
* The {@code Long} class is the {@linkplain
|
||||
@ -311,7 +313,36 @@ public final class Long extends Number
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public static String toHexString(long i) {
|
||||
return toUnsignedString0(i, 4);
|
||||
int mag = Long.SIZE - Long.numberOfLeadingZeros(i);
|
||||
int len = Math.max(((mag + 3) / 4), 1);
|
||||
byte coder = COMPACT_STRINGS ? LATIN1 : UTF16;
|
||||
byte[] chars = new byte[len << coder];
|
||||
byte b;
|
||||
long x = Integer.hex8(i);
|
||||
if (len > 8) {
|
||||
if (COMPACT_STRINGS) {
|
||||
len -= 8;
|
||||
Unsafe.getUnsafe().putLong(chars, ARRAY_BYTE_BASE_OFFSET + len, Long.reverseBytes(x));
|
||||
} else {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
b = (byte) x;
|
||||
StringUTF16.putChar(chars, --len, b);
|
||||
x >>>= 8;
|
||||
}
|
||||
}
|
||||
x = Integer.hex8(i >>> 32);
|
||||
}
|
||||
do {
|
||||
--len;
|
||||
b = (byte) x;
|
||||
if (COMPACT_STRINGS) {
|
||||
chars[len] = b;
|
||||
} else {
|
||||
StringUTF16.putChar(chars, len, b);
|
||||
}
|
||||
x >>>= 8;
|
||||
} while (len > 0);
|
||||
return new String(chars, coder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user