Skip to content

Commit d0e8aec

Browse files
author
Brian Burkhalter
committed
8306374: (bf) Improve performance of DirectCharBuffer::append(CharSequence[,int,int])
Reviewed-by: liach, alanb
1 parent a18191f commit d0e8aec

File tree

6 files changed

+142
-19
lines changed

6 files changed

+142
-19
lines changed

src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,69 @@ class Direct$Type$Buffer$RW$$BO$
446446

447447
// --- Methods to support CharSequence ---
448448

449+
#if[rw]
450+
private static final int APPEND_BUF_SIZE = 1024;
451+
452+
private $Type$Buffer appendChars(CharSequence csq, int start, int end) {
453+
Objects.checkFromToIndex(start, end, csq.length());
454+
455+
int pos = position();
456+
int lim = limit();
457+
int rem = (pos <= lim) ? lim - pos : 0;
458+
int length = end - start;
459+
if (length > rem)
460+
throw new BufferOverflowException();
461+
462+
char[] buf = new char[Math.min(APPEND_BUF_SIZE, length)];
463+
int index = pos;
464+
while (start < end) {
465+
int count = end - start;
466+
if (count > buf.length)
467+
count = buf.length;
468+
469+
if (csq instanceof String str) {
470+
str.getChars(start, start + count, buf, 0);
471+
} else if (csq instanceof StringBuilder sb) {
472+
sb.getChars(start, start + count, buf, 0);
473+
} else if (csq instanceof StringBuffer sb) {
474+
sb.getChars(start, start + count, buf, 0);
475+
}
476+
477+
putArray(index, buf, 0, count);
478+
479+
start += count;
480+
index += count;
481+
}
482+
483+
position(pos + length);
484+
485+
return this;
486+
}
487+
#end[rw]
488+
489+
public $Type$Buffer append(CharSequence csq) {
490+
#if[rw]
491+
if (csq instanceof StringBuilder)
492+
return appendChars(csq, 0, csq.length());
493+
494+
return super.append(csq);
495+
#else[rw]
496+
throw new ReadOnlyBufferException();
497+
#end[rw]
498+
}
499+
500+
public $Type$Buffer append(CharSequence csq, int start, int end) {
501+
#if[rw]
502+
if (csq instanceof String || csq instanceof StringBuffer ||
503+
csq instanceof StringBuilder)
504+
return appendChars(csq, start, end);
505+
506+
return super.append(csq, start, end);
507+
#else[rw]
508+
throw new ReadOnlyBufferException();
509+
#end[rw]
510+
}
511+
449512
public CharBuffer subSequence(int start, int end) {
450513
int pos = position();
451514
int lim = limit();

src/java.base/share/classes/java/nio/X-Buffer.java.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,7 @@ public abstract sealed class $Type$Buffer
13191319
return put(index, src, 0, src.length);
13201320
}
13211321

1322-
private $Type$Buffer putArray(int index, $type$[] src, int offset, int length) {
1322+
$Type$Buffer putArray(int index, $type$[] src, int offset, int length) {
13231323
#if[rw]
13241324
if (
13251325
#if[char]

test/jdk/java/nio/Buffer/Basic-X.java.template

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ import java.nio.file.Files;
4141
import java.nio.file.Path;
4242
import java.util.Random;
4343
#end[byte]
44+
#if[char]
45+
import java.util.function.IntFunction;
46+
#end[char]
4447

4548

4649
public class Basic$Type$
@@ -646,15 +649,24 @@ public class Basic$Type$
646649
{cslen/2, cslen + 1} // end > cslen
647650
};
648651

649-
for (CharSequence csq : csqs) {
650-
// append() should throw BufferOverflowException
651-
tryCatch(b, BufferOverflowException.class, () ->
652-
CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2));
652+
IntFunction<CharBuffer>[] producers = new IntFunction[] {
653+
(i) -> CharBuffer.allocate(i),
654+
(i) -> ByteBuffer.allocateDirect(2*i).asCharBuffer()
655+
};
653656

654-
// append() should throw IndexOutOfBoundsException
655-
for (int[] bds : bounds)
656-
tryCatch(b, IndexOutOfBoundsException.class, () ->
657-
CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1]));
657+
for (IntFunction<CharBuffer> f : producers) {
658+
for (CharSequence csq : csqs) {
659+
// append() should throw BufferOverflowException
660+
final CharBuffer cbBOE = f.apply(cslen/8);
661+
tryCatch(cbBOE, BufferOverflowException.class, () ->
662+
cbBOE.append(csq, cslen/4, cslen/2));
663+
664+
// append() should throw IndexOutOfBoundsException
665+
final CharBuffer cbIOOBE = f.apply(cslen + 1);
666+
for (int[] bds : bounds)
667+
tryCatch(cbIOOBE, IndexOutOfBoundsException.class, () ->
668+
cbIOOBE.append(csq, bds[0], bds[1]));
669+
}
658670
}
659671
// end 8306623
660672

test/jdk/java/nio/Buffer/Basic.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
2727
* 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431
2828
* 5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219
29-
* 7199551 8065556 8149469 8230665 8237514 8306623
29+
* 7199551 8065556 8149469 8230665 8237514 8306374 8306623
3030
* @modules java.base/java.nio:open
3131
* java.base/jdk.internal.misc
3232
* @author Mark Reinhold

test/jdk/java/nio/Buffer/BasicChar.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242

4343

4444

45+
import java.util.function.IntFunction;
46+
47+
4548

4649
public class BasicChar
4750
extends Basic
@@ -646,15 +649,24 @@ public static void test(int level, final CharBuffer b, boolean direct) {
646649
{cslen/2, cslen + 1} // end > cslen
647650
};
648651

649-
for (CharSequence csq : csqs) {
650-
// append() should throw BufferOverflowException
651-
tryCatch(b, BufferOverflowException.class, () ->
652-
CharBuffer.allocate(cslen/8).append(csq, cslen/4, cslen/2));
652+
IntFunction<CharBuffer>[] producers = new IntFunction[] {
653+
(i) -> CharBuffer.allocate(i),
654+
(i) -> ByteBuffer.allocateDirect(2*i).asCharBuffer()
655+
};
653656

654-
// append() should throw IndexOutOfBoundsException
655-
for (int[] bds : bounds)
656-
tryCatch(b, IndexOutOfBoundsException.class, () ->
657-
CharBuffer.allocate(cslen + 1).append(csq, bds[0], bds[1]));
657+
for (IntFunction<CharBuffer> f : producers) {
658+
for (CharSequence csq : csqs) {
659+
// append() should throw BufferOverflowException
660+
final CharBuffer cbBOE = f.apply(cslen/8);
661+
tryCatch(cbBOE, BufferOverflowException.class, () ->
662+
cbBOE.append(csq, cslen/4, cslen/2));
663+
664+
// append() should throw IndexOutOfBoundsException
665+
final CharBuffer cbIOOBE = f.apply(cslen + 1);
666+
for (int[] bds : bounds)
667+
tryCatch(cbIOOBE, IndexOutOfBoundsException.class, () ->
668+
cbIOOBE.append(csq, bds[0], bds[1]));
669+
}
658670
}
659671
// end 8306623
660672

test/micro/org/openjdk/bench/java/nio/CharBufferAppend.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
@Fork(1)
4545
public class CharBufferAppend {
4646

47-
static final int SIZE = 8192;
47+
static final int SIZE = 32768;
4848

4949
static String str;
5050
static StringBuffer strbuf;
@@ -138,4 +138,40 @@ public CharBuffer appendSubStringBuilder() {
138138
hbDst.clear();
139139
return hbDst.append(strbld, SIZE/4, 3*SIZE/4);
140140
}
141+
142+
@Benchmark
143+
public CharBuffer appendStringToDirect() {
144+
dbDst.clear();
145+
return dbDst.append(str);
146+
}
147+
148+
@Benchmark
149+
public CharBuffer appendStringBufferToDirect() {
150+
dbDst.clear();
151+
return dbDst.append(strbuf);
152+
}
153+
154+
@Benchmark
155+
public CharBuffer appendStringBuilderToDirect() {
156+
dbDst.clear();
157+
return dbDst.append(strbld);
158+
}
159+
160+
@Benchmark
161+
public CharBuffer appendSubStringToDirect() {
162+
dbDst.clear();
163+
return dbDst.append(str, SIZE/4, 3*SIZE/4);
164+
}
165+
166+
@Benchmark
167+
public CharBuffer appendSubStringBufferToDirect() {
168+
dbDst.clear();
169+
return dbDst.append(strbuf, SIZE/4, 3*SIZE/4);
170+
}
171+
172+
@Benchmark
173+
public CharBuffer appendSubStringBuilderToDirect() {
174+
dbDst.clear();
175+
return dbDst.append(strbld, SIZE/4, 3*SIZE/4);
176+
}
141177
}

0 commit comments

Comments
 (0)