mirror of
https://github.com/alibaba/fastjson.git
synced 2026-10-22 01:06:23 +08:00
Merge pull request #223 from alibaba/revert-222-master
Revert "Optimize ThreadLocalCache while perusal the code."
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user