avoid allocating sun.nio.cs.US_ASCII$Decoder when converting byte[] to String

: 1,267,720,880 (3%) bytes in 31,693,022 (3%) objects (avg size 40 bytes)
                 	sun.nio.cs.US_ASCII.newDecoder: 1,267,720,880 (100%) bytes in 31,693,022 (100%) objects
                 		java.lang.String.<init>: 1,267,673,560 (99%) bytes in 31,691,839 (99%) objects
                 			com.intellij.util.io.IOUtil.readUTFFast: 1,267,673,480 (99%) bytes in 31,691,837 (99%) objects
This commit is contained in:
Maxim.Mossienko
2013-12-10 16:12:47 +01:00
parent 5478fdf0b1
commit cf71d6bd2c
@@ -18,6 +18,7 @@ package com.intellij.util.io;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.reference.SoftReference;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -113,6 +114,8 @@ public class IOUtil {
}
public static final Charset US_ASCII = Charset.forName("US-ASCII");
private static final ThreadLocal<SoftReference<char[]>> spareBufferLocal = new ThreadLocal<SoftReference<char[]>>();
public static String readUTFFast(@NotNull byte[] buffer, @NotNull DataInput storage) throws IOException {
int len = 0xFF & (int)storage.readByte();
if (len == 0xFF) {
@@ -126,7 +129,15 @@ public class IOUtil {
if (len == 0) return "";
storage.readFully(buffer, 0, len);
return new String(buffer, 0, len, US_ASCII);
SoftReference<char[]> reference = spareBufferLocal.get();
char[] chars = reference != null ? reference.get() : null;
if (chars == null) {
chars = new char[STRING_LENGTH_THRESHOLD];
spareBufferLocal.set(new SoftReference<char[]>(chars));
}
for(int i = 0; i < len; ++i) chars[i] = (char)(buffer[i] &0xFF);
return new String(chars, 0, len);
}
public static boolean isAscii(@NotNull String str) {