Merge pull request #223 from alibaba/revert-222-master

Revert "Optimize ThreadLocalCache while perusal the code."
This commit is contained in:
高铁
2014-09-30 05:18:23 +08:00
2 changed files with 20 additions and 111 deletions
@@ -5,10 +5,8 @@ import java.nio.charset.CharsetDecoder;
public class ThreadLocalCache {
public final static int CHARS_CACH_INIT_SIZE = 1024; // 1k, 2^10;
public final static int CHARS_CACH_INIT_SIZE_EXP = 10;
public final static int CHARS_CACH_MAX_SIZE = 1024 * 128; // 128k, 2^17;
public final static int CHARS_CACH_MAX_SIZE_EXP = 17;
public final static int CHARS_CACH_INIT_SIZE = 1024; // 1k;
public final static int CHARS_CACH_MAX_SIZE = 1024 * 128; // 1k;
private final static ThreadLocal<SoftReference<char[]>> charsBufLocal = new ThreadLocal<SoftReference<char[]>>();
private final static ThreadLocal<CharsetDecoder> decoderLocal = new ThreadLocal<CharsetDecoder>();
@@ -47,30 +45,17 @@ public class ThreadLocalCache {
}
private static char[] allocate(int length) {
if(length> CHARS_CACH_MAX_SIZE) {
return new char[length];
}
int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length);
int allocateLength = getAllocateLengthExp(CHARS_CACH_INIT_SIZE_EXP, CHARS_CACH_MAX_SIZE_EXP, length);
char[] chars = new char[allocateLength];
charsBufLocal.set(new SoftReference<char[]>(chars));
return chars;
if (allocateLength <= CHARS_CACH_MAX_SIZE) {
char[] chars = new char[allocateLength];
charsBufLocal.set(new SoftReference<char[]>(chars));
return chars;
}
return new char[length];
}
private static int getAllocateLengthExp(int minExp, int maxExp, int length) {
assert maxExp >= length;
// int max = 1 << maxExp;
// if(length>= max) {
// return length;
// }
int part = length >>> minExp;
if(part <= 0) {
return 1<< minExp;
}
return 1 << 32 - Integer.numberOfLeadingZeros(length-1);
}
@Deprecated
private static int getAllocateLength(int init, int max, int length) {
int value = init;
for (;;) {
@@ -89,10 +74,8 @@ public class ThreadLocalCache {
}
// /////////
public final static int BYTES_CACH_INIT_SIZE = 1024; // 1k, 2^10;
public final static int BYTES_CACH_INIT_SIZE_EXP = 10;
public final static int BYTES_CACH_MAX_SIZE = 1024 * 128; // 128k, 2^17;
public final static int BYTES_CACH_MAX_SIZE_EXP = 17;
public final static int BYTES_CACH_INIT_SIZE = 1024; // 1k;
public final static int BYTeS_CACH_MAX_SIZE = 1024 * 128; // 1k;
private final static ThreadLocal<SoftReference<byte[]>> bytesBufLocal = new ThreadLocal<SoftReference<byte[]>>();
public static void clearBytes() {
@@ -120,14 +103,15 @@ public class ThreadLocalCache {
}
private static byte[] allocateBytes(int length) {
if(length > CHARS_CACH_MAX_SIZE) {
return new byte[length];
}
int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length);
int allocateLength = getAllocateLengthExp(CHARS_CACH_INIT_SIZE_EXP, CHARS_CACH_MAX_SIZE_EXP, length);
byte[] chars = new byte[allocateLength];
bytesBufLocal.set(new SoftReference<byte[]>(chars));
return chars;
if (allocateLength <= CHARS_CACH_MAX_SIZE) {
byte[] chars = new byte[allocateLength];
bytesBufLocal.set(new SoftReference<byte[]>(chars));
return chars;
}
return new byte[length];
}
}
@@ -1,75 +0,0 @@
package com.alibaba.json.bvt.util;
import java.lang.reflect.Method;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.alibaba.fastjson.util.ThreadLocalCache;
import static com.alibaba.fastjson.util.ThreadLocalCache.CHARS_CACH_INIT_SIZE;
import static com.alibaba.fastjson.util.ThreadLocalCache.CHARS_CACH_INIT_SIZE_EXP;
import static com.alibaba.fastjson.util.ThreadLocalCache.CHARS_CACH_MAX_SIZE;
import static com.alibaba.fastjson.util.ThreadLocalCache.CHARS_CACH_MAX_SIZE_EXP;
/**
* Test new {@link #getAllocateLengthExp(int, int, int)} comparing with old
* {@link #getAllocateLength(int, int, int)} method in {@link ThreadLocalCache}.
*/
public class TheradLocalCacheUnitTest {
static Method getAllocateLengthMethod;
static Method getAllocateLengthExpMethod;
@BeforeClass
public static void init() throws Exception {
getAllocateLengthMethod = ThreadLocalCache.class.getDeclaredMethod("getAllocateLength",
int.class, int.class, int.class);
getAllocateLengthExpMethod = ThreadLocalCache.class.getDeclaredMethod(
"getAllocateLengthExp", int.class, int.class, int.class);
getAllocateLengthMethod.setAccessible(true);
getAllocateLengthExpMethod.setAccessible(true);
}
@Test
public void getAllocateLengthNewImplementationRandomTest() throws Exception {
Random random = ThreadLocalRandom.current();
for (int i = 0; i < 100000000; i++) {
int length = Math.abs(random.nextInt());
testSample(length);
}
}
@Test
public void getAllocateLengthNewImplementationCertainTest() throws Exception {
testSample(0);
testSample(1);
testSample(1024);
testSample(CHARS_CACH_INIT_SIZE);
testSample(CHARS_CACH_MAX_SIZE);
testSample(114649);
}
private void testSample(int length) throws Exception {
if (length > CHARS_CACH_MAX_SIZE) {
return;
}
int oldWay = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length);
int newWay = getAllocateLengthExp(CHARS_CACH_INIT_SIZE_EXP, CHARS_CACH_MAX_SIZE_EXP, length);
// since new method always need premise length <= max value. we need to
// skip this case.
Assert.assertEquals("error when test length:" + length, oldWay, newWay);
}
private static int getAllocateLength(int init, int max, int length) throws Exception {
return (Integer) getAllocateLengthMethod.invoke(null, init, max, length);
}
private static int getAllocateLengthExp(int minExp, int maxExp, int length) throws Exception {
return (Integer) getAllocateLengthExpMethod.invoke(null, minExp, maxExp, length);
}
}