-
Enhancement
-
Resolution: Fixed
-
P3
-
None
-
b10
A DESCRIPTION OF THE REQUEST :
CharBuffer.put(String) and CharBuffer.put(String,int,int) calls charAt() to retrieve the content of String as follows:
public CharBuffer put(String src, int start, int end) {
checkBounds(start, end - start, src.length());
for (int i = start; i < end; i++)
this.put(src.charAt(i));
return this;
}
This is very slow even for a String of moderate length (20-40 chars).
Compared to char[] version, this makes serialization of String several times slower.
As java.nio is JDK's internal package, this should use sun.misc.Unsafe to retrieve the internal char[] of String and just call put(char[]).
JUSTIFICATION :
For user programs, String is heavily protected and there is no recommended way to retrieve its char[] without making extra copy. So, CharBuffer.put(String) is the only bulk interface available to users, which is very slow because of this issue.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Process String serialization as a batch/bulk.
ACTUAL -
Calls charAt() and put() for every character.
---------- BEGIN SOURCE ----------
import java.nio.CharBuffer;
public class Test {
public static void main(String[] args) {
String str = new String ( " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 " );
CharBuffer buf = CharBuffer.wrap(new char[100]);
int REP = 1 << 22;
{
long st = System.currentTimeMillis();
for (int i = 0; i < REP; ++i) {
buf.position(0);
buf.put(str);
}
long ed = System.currentTimeMillis();
System.out.println ( " put(String): " + (ed - st) + " ms " );
}
char[] chars = str.toCharArray(); // extra copy
{
long st = System.currentTimeMillis();
for (int i = 0; i < REP; ++i) {
buf.position(0);
buf.put(chars);
}
long ed = System.currentTimeMillis();
System.out.println ( " put(char[]): " + (ed - st) + " ms " );
}
}
}
== Result
put(String):221ms
put(char[]):57ms
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Either use sun.misc.Unsafe in user code (not recommended at all) or copy char[] from String using toCharArray()/copyValueOf() (extra overhead/footprint).
CharBuffer.put(String) and CharBuffer.put(String,int,int) calls charAt() to retrieve the content of String as follows:
public CharBuffer put(String src, int start, int end) {
checkBounds(start, end - start, src.length());
for (int i = start; i < end; i++)
this.put(src.charAt(i));
return this;
}
This is very slow even for a String of moderate length (20-40 chars).
Compared to char[] version, this makes serialization of String several times slower.
As java.nio is JDK's internal package, this should use sun.misc.Unsafe to retrieve the internal char[] of String and just call put(char[]).
JUSTIFICATION :
For user programs, String is heavily protected and there is no recommended way to retrieve its char[] without making extra copy. So, CharBuffer.put(String) is the only bulk interface available to users, which is very slow because of this issue.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Process String serialization as a batch/bulk.
ACTUAL -
Calls charAt() and put() for every character.
---------- BEGIN SOURCE ----------
import java.nio.CharBuffer;
public class Test {
public static void main(String[] args) {
String str = new String ( " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 " );
CharBuffer buf = CharBuffer.wrap(new char[100]);
int REP = 1 << 22;
{
long st = System.currentTimeMillis();
for (int i = 0; i < REP; ++i) {
buf.position(0);
buf.put(str);
}
long ed = System.currentTimeMillis();
System.out.println ( " put(String): " + (ed - st) + " ms " );
}
char[] chars = str.toCharArray(); // extra copy
{
long st = System.currentTimeMillis();
for (int i = 0; i < REP; ++i) {
buf.position(0);
buf.put(chars);
}
long ed = System.currentTimeMillis();
System.out.println ( " put(char[]): " + (ed - st) + " ms " );
}
}
}
== Result
put(String):221ms
put(char[]):57ms
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Either use sun.misc.Unsafe in user code (not recommended at all) or copy char[] from String using toCharArray()/copyValueOf() (extra overhead/footprint).
- relates to
-
JDK-8219597 (bf) Heap buffer state changes could provoke unexpected exceptions
- Closed
- links to