Skip to content

Commit e2feff8

Browse files
committed
8355177: Speed up StringBuilder::append(char[]) via Unsafe::copyMemory
Reviewed-by: rriggs, rgiulietti
1 parent 16da81e commit e2feff8

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

src/java.base/share/classes/java/lang/StringUTF16.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -1312,12 +1313,6 @@ static Stream<String> lines(byte[] value) {
13121313
return StreamSupport.stream(LinesSpliterator.spliterator(value), false);
13131314
}
13141315

1315-
private static void putChars(byte[] val, int index, char[] str, int off, int end) {
1316-
while (off < end) {
1317-
putChar(val, index++, str[off++]);
1318-
}
1319-
}
1320-
13211316
public static String newString(byte[] val, int index, int len) {
13221317
if (len == 0) {
13231318
return "";
@@ -1486,7 +1481,13 @@ public static void putCharSB(byte[] val, int index, int c) {
14861481

14871482
public static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) {
14881483
checkBoundsBeginEnd(index, index + end - off, val);
1489-
putChars(val, index, ca, off, end);
1484+
String.checkBoundsBeginEnd(off, end, ca.length);
1485+
Unsafe.getUnsafe().copyMemory(
1486+
ca,
1487+
Unsafe.ARRAY_CHAR_BASE_OFFSET + ((long) off << 1),
1488+
val,
1489+
Unsafe.ARRAY_BYTE_BASE_OFFSET + ((long) index << 1),
1490+
(long) (end - off) << 1);
14901491
}
14911492

14921493
public static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) {

test/micro/org/openjdk/bench/java/lang/StringBuilders.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
2-
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2025, Alibaba Group Holding Limited. All Rights Reserved.
34
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45
*
56
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +51,7 @@ public class StringBuilders {
5051
private String[] str16p8p7;
5152
private String[] str3p9p8;
5253
private String[] str22p40p31;
54+
private char[][] charArray22p40p31;
5355
private StringBuilder sbLatin1;
5456
private StringBuilder sbLatin2;
5557
private StringBuilder sbUtf16;
@@ -63,10 +65,15 @@ public void setup() {
6365
"advise", "you", "to", "drive", "at", "top", "speed", "it'll",
6466
"be", "a", "god", "damn", "miracle", "if", "we", "can", "get",
6567
"there", "before", "you", "turn", "into", "a", "wild", "animal."};
68+
6669
str3p4p2 = new String[]{"123", "1234", "12"};
6770
str16p8p7 = new String[]{"1234567890123456", "12345678", "1234567"};
6871
str3p9p8 = new String[]{"123", "123456789", "12345678"};
6972
str22p40p31 = new String[]{"1234567890123456789012", "1234567890123456789012345678901234567890", "1234567890123456789012345678901"};
73+
charArray22p40p31 = new char[str22p40p31.length][];
74+
for (int i = 0; i < str22p40p31.length; i++) {
75+
charArray22p40p31[i] = str22p40p31[i].toCharArray();
76+
}
7077
sbLatin1 = new StringBuilder("Latin1 string");
7178
sbLatin2 = new StringBuilder("Latin1 string");
7279
sbUtf16 = new StringBuilder("UTF-\uFF11\uFF16 string");
@@ -273,6 +280,24 @@ public int appendWithLongUtf16() {
273280
return buf.length();
274281
}
275282

283+
@Benchmark
284+
public int appendWithCharArrayLatin1() {
285+
StringBuilder buf = new StringBuilder();
286+
for (char[] charArray : charArray22p40p31) {
287+
buf.append(charArray);
288+
}
289+
return buf.length();
290+
}
291+
292+
@Benchmark
293+
public int appendWithCharArrayUTF16() {
294+
StringBuilder buf = new StringBuilder("\uFF11");
295+
for (char[] charArray : charArray22p40p31) {
296+
buf.append(charArray);
297+
}
298+
return buf.length();
299+
}
300+
276301
@Benchmark
277302
public String toStringCharWithBool8() {
278303
StringBuilder result = new StringBuilder();

0 commit comments

Comments
 (0)