优化掉Array.newInstance

This commit is contained in:
redkale
2023-02-02 23:16:24 +08:00
parent 6973e6b159
commit de39ac1981
12 changed files with 72 additions and 49 deletions

View File

@@ -1247,9 +1247,9 @@ public class HttpRequest extends Request<HttpContext> {
*/
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
if (this.annotations == null) {
return Creator.arrayFunction(annotationClass).apply(0);
return Creator.newArray(annotationClass, 0);
}
T[] news = Creator.arrayFunction(annotationClass).apply(this.annotations.length);
T[] news = Creator.newArray(annotationClass, this.annotations.length);
int index = 0;
for (Annotation ann : this.annotations) {
if (ann.getClass() == annotationClass) {
@@ -1257,7 +1257,7 @@ public class HttpRequest extends Request<HttpContext> {
}
}
if (index < 1) {
return Creator.arrayFunction(annotationClass).apply(0);
return Creator.newArray(annotationClass, 0);
}
return Arrays.copyOf(news, index);
}

View File

@@ -713,7 +713,7 @@ public final class Rest {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynSuperMessageFullName, en.getKey(), Type.getDescriptor(paramType));
if (paramType.isPrimitive()) {
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(paramType, 1), 0).getClass();
Class bigclaz = TypeToken.primitiveToWrapper(paramType);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(paramType) + ")" + Type.getDescriptor(bigclaz), false);
}
mv.visitInsn(ARETURN);

View File

@@ -37,9 +37,9 @@ public interface WebSocketParam {
default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Annotation[] annotations = getAnnotations();
if (annotations == null) {
return Creator.arrayFunction(annotationClass).apply(0);
return Creator.newArray(annotationClass, 0);
}
T[] news = Creator.arrayFunction(annotationClass).apply(annotations.length);
T[] news = Creator.newArray(annotationClass, annotations.length);
int index = 0;
for (Annotation ann : annotations) {
if (ann.getClass() == annotationClass) {
@@ -47,7 +47,7 @@ public interface WebSocketParam {
}
}
if (index < 1) {
return Creator.arrayFunction(annotationClass).apply(0);
return Creator.newArray(annotationClass, 0);
}
return Arrays.copyOf(news, index);
}

View File

@@ -830,7 +830,7 @@ public abstract class Sncp {
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance((Class) pt, 1), 0).getClass();
Class bigclaz = TypeToken.primitiveToWrapper((Class) pt);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false);
} else {
mv.visitVarInsn(ALOAD, insn);
@@ -846,7 +846,7 @@ public abstract class Sncp {
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
Class bigPrimitiveClass = returnclz.isPrimitive() ? java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(returnclz, 1), 0).getClass() : returnclz;
Class bigPrimitiveClass = returnclz.isPrimitive() ? TypeToken.primitiveToWrapper(returnclz) : returnclz;
mv.visitTypeInsn(CHECKCAST, (returnclz.isPrimitive() ? bigPrimitiveClass : returnclz).getName().replace('.', '/'));
if (returnclz.isPrimitive()) {
String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');

View File

@@ -52,7 +52,7 @@ public final class SncpDynServlet extends SncpServlet {
for (Map.Entry<Uint128, Method> en : SncpOldClient.parseMethodActions(service.getClass()).entrySet()) {
SncpServletAction action;
try {
action = SncpServletAction.create(service, en.getKey(), en.getValue());
action = SncpServletAction.create(service, serviceid, en.getKey(), en.getValue());
} catch (RuntimeException e) {
throw new SncpException(en.getValue() + " create " + SncpServletAction.class.getSimpleName() + " error", e);
}
@@ -111,12 +111,12 @@ public final class SncpDynServlet extends SncpServlet {
SncpAsyncHandler handler = null;
try {
if (action.handlerFuncParamIndex >= 0) {
if (action.handlerFuncParamClass == CompletionHandler.class) {
if (action.handlerFuncParamType == CompletionHandler.class) {
handler = new DefaultSncpAsyncHandler(logger, action, in, out, request, response);
} else {
Creator<SncpAsyncHandler> creator = action.handlerCreator;
if (creator == null) {
creator = SncpAsyncHandler.Factory.createCreator(action.handlerFuncParamClass);
creator = SncpAsyncHandler.Factory.createCreator(action.handlerFuncParamType);
action.handlerCreator = creator;
}
handler = creator.create(new DefaultSncpAsyncHandler(logger, action, in, out, request, response));
@@ -173,9 +173,9 @@ public final class SncpDynServlet extends SncpServlet {
protected int handlerFuncParamIndex = -1; //handlerFuncParamIndex>=0表示存在CompletionHandler参数
protected boolean boolReturnTypeFuture = false; // 返回结果类型是否为 CompletableFuture
protected Class handlerFuncParamType; //CompletionHandler参数的类型
protected Class handlerFuncParamClass; //CompletionHandler参数的类型
protected boolean boolReturnTypeFuture = false; // 返回结果类型是否为 CompletableFuture
public abstract void action(final BsonReader in, final BsonWriter out, final SncpAsyncHandler handler) throws Throwable;
@@ -285,14 +285,15 @@ public final class SncpDynServlet extends SncpServlet {
*
* </pre></blockquote>
*
* @param service Service
* @param actionid 操作ID
* @param method 方法
* @param service Service
* @param serviceid ID
* @param actionid 操作ID
* @param method 方法
*
* @return SncpServletAction
*/
@SuppressWarnings("unchecked")
public static SncpServletAction create(final Service service, final Uint128 actionid, final Method method) {
public static SncpServletAction create(final Service service, final Uint128 serviceid, final Uint128 actionid, final Method method) {
final Class serviceClass = service.getClass();
final String supDynName = SncpServletAction.class.getName().replace('.', '/');
final String serviceName = serviceClass.getName().replace('.', '/');
@@ -306,7 +307,7 @@ public final class SncpDynServlet extends SncpServlet {
final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__" + serviceClass.getName().replace('.', '_').replace('$', '_') + "__" + method.getName() + "__" + actionid;
int handlerFuncIndex = -1;
Class handlerFuncClass = null;
Class handlerFuncType = null;
Class<?> newClazz = null;
try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
@@ -315,7 +316,7 @@ public final class SncpDynServlet extends SncpServlet {
for (int i = 0; i < paramClasses.length; i++) { //反序列化方法的每个参数
if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
handlerFuncIndex = i;
handlerFuncClass = paramClasses[i];
handlerFuncType = paramClasses[i];
break;
}
}
@@ -370,7 +371,7 @@ public final class SncpDynServlet extends SncpServlet {
}
Sncp.checkAsyncModifier(paramClasses[i], method);
handlerFuncIndex = i;
handlerFuncClass = paramClasses[i];
handlerFuncType = paramClasses[i];
mv.visitVarInsn(ALOAD, 3);
mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/'));
mv.visitVarInsn(ASTORE, store);
@@ -422,7 +423,7 @@ public final class SncpDynServlet extends SncpServlet {
load = DLOAD;
v = 1;
}
Class bigPrimitiveClass = Array.get(Array.newInstance(paramClasses[i], 1), 0).getClass();
Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]);
String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');
try {
Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value");
@@ -479,7 +480,7 @@ public final class SncpDynServlet extends SncpServlet {
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(pt, 1), 0).getClass();
Class bigclaz = TypeToken.primitiveToWrapper(pt);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false);
} else {
mv.visitVarInsn(ALOAD, insn);
@@ -500,7 +501,7 @@ public final class SncpDynServlet extends SncpServlet {
final Class returnClass = method.getReturnType();
if (returnClass != void.class) {
if (returnClass.isPrimitive()) {
Class bigClass = Array.get(Array.newInstance(returnClass, 1), 0).getClass();
Class bigClass = TypeToken.primitiveToWrapper(returnClass);
try {
Method vo = bigClass.getMethod("valueOf", returnClass);
mv.visitMethodInsn(INVOKESTATIC, bigClass.getName().replace('.', '/'), vo.getName(), Type.getMethodDescriptor(vo), false);
@@ -553,7 +554,7 @@ public final class SncpDynServlet extends SncpServlet {
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(pt, 1), 0).getClass();
Class bigclaz = TypeToken.primitiveToWrapper(pt);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false);
} else {
mv.visitVarInsn(ALOAD, insn);
@@ -626,7 +627,7 @@ public final class SncpDynServlet extends SncpServlet {
System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length);
instance.paramTypes = types;
instance.handlerFuncParamIndex = handlerFuncIndex;
instance.handlerFuncParamClass = handlerFuncClass;
instance.handlerFuncParamType = handlerFuncType;
instance.boolReturnTypeFuture = boolReturnTypeFuture;
newClazz.getField("service").set(instance, service);
return instance;

View File

@@ -53,7 +53,7 @@ public interface CacheSource extends Resourcable {
public Map<String, byte[]> mgetBytes(final String... keys);
default <T> T[] mgets(final Type componentType, final String... keys) {
T[] rs = (T[]) Creator.arrayFunction(TypeToken.typeToClass(componentType)).apply(keys.length);
T[] rs = (T[]) Creator.newArray(TypeToken.typeToClass(componentType), keys.length);
Map<String, T> map = mget(componentType, keys);
for (int i = 0; i < keys.length; i++) {
rs[i] = map.get(keys[i]);
@@ -335,7 +335,7 @@ public interface CacheSource extends Resourcable {
default <T> CompletableFuture<T[]> mgetsAsync(final Type componentType, final String... keys) {
return mgetAsync(componentType, keys).thenApply(map -> {
T[] rs = (T[]) Creator.arrayFunction(TypeToken.typeToClass(componentType)).apply(keys.length);
T[] rs = (T[]) Creator.newArray(TypeToken.typeToClass(componentType), keys.length);
for (int i = 0; i < keys.length; i++) {
rs[i] = (T) map.get(keys[i]);
}

View File

@@ -6,7 +6,6 @@
package org.redkale.source;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
@@ -834,9 +833,9 @@ public final class EntityCache<T> {
public T[] update(final T entity, final Collection<Attribute<T, Serializable>> attrs, final FilterNode node) {
if (entity == null || node == null) {
return (T[]) Array.newInstance(type, 0);
return (T[]) Creator.newArray(type, 0);
}
T[] rms = this.list.stream().filter(node.createPredicate(this)).toArray(len -> (T[]) Array.newInstance(type, len));
T[] rms = this.list.stream().filter(node.createPredicate(this)).toArray(Creator.arrayFunction(type));
tableLock.lock(); //表锁, 可优化成行锁
try {
for (T rs : rms) {
@@ -863,9 +862,9 @@ public final class EntityCache<T> {
public <V> T[] update(Attribute<T, V> attr, final V fieldValue, final FilterNode node) {
if (attr == null || node == null) {
return (T[]) Array.newInstance(type, 0);
return (T[]) Creator.newArray(type, 0);
}
T[] rms = this.list.stream().filter(node.createPredicate(this)).toArray(len -> (T[]) Array.newInstance(type, len));
T[] rms = this.list.stream().filter(node.createPredicate(this)).toArray(Creator.arrayFunction(type));
for (T rs : rms) {
attr.set(rs, fieldValue);
}
@@ -894,7 +893,7 @@ public final class EntityCache<T> {
public <V> T[] updateColumn(final FilterNode node, final Flipper flipper, List<Attribute<T, Serializable>> attrs, final List<ColumnValue> values) {
if (attrs == null || attrs.isEmpty() || node == null) {
return (T[]) Array.newInstance(type, 0);
return (T[]) Creator.newArray(type, 0);
}
Stream<T> stream = this.list.stream();
final Comparator<T> comparator = createComparator(flipper);
@@ -904,7 +903,7 @@ public final class EntityCache<T> {
if (flipper != null && flipper.getLimit() > 0) {
stream = stream.limit(flipper.getLimit());
}
T[] rms = stream.filter(node.createPredicate(this)).toArray(len -> (T[]) Array.newInstance(type, len));
T[] rms = stream.filter(node.createPredicate(this)).toArray(Creator.arrayFunction(type));
tableLock.lock(); //表锁, 可优化成行锁
try {
for (T rs : rms) {

View File

@@ -9,8 +9,8 @@ import java.lang.reflect.TypeVariable;
import java.util.*;
import java.util.function.*;
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.*;
import static org.redkale.asm.Opcodes.*;
import org.redkale.util.Attribute;
/**
@@ -802,7 +802,7 @@ public interface Attribute<T, F> {
}
final Class pcolumn = column;
if (column.isPrimitive()) {
column = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(column, 1), 0).getClass();
column = TypeToken.primitiveToWrapper(column);
}
final String supDynName = Attribute.class.getName().replace('.', '/');
final String interName = TypeToken.typeToClass(subclass).getName().replace('.', '/');

View File

@@ -143,7 +143,6 @@ public interface Creator<T> {
if (type == double.class) {
return (T[]) (Object) new double[size];
}
//return (T[]) Array.newInstance(type, size);
return arrayFunction(type).apply(size);
}
@@ -491,7 +490,7 @@ public interface Creator<T> {
mv.visitInsn(AALOAD);
final Class ct = constructorParameters[i].getValue();
if (ct.isPrimitive()) {
final Class bigct = Array.get(Array.newInstance(ct, 1), 0).getClass();
final Class bigct = TypeToken.primitiveToWrapper(ct);
mv.visitTypeInsn(CHECKCAST, bigct.getName().replace('.', '/'));
try {
Method pm = bigct.getMethod(ct.getSimpleName() + "Value");

View File

@@ -1091,7 +1091,7 @@ public final class ResourceFactory {
}
}
if (newVal == null && classType.isPrimitive()) {
newVal = Array.get(Array.newInstance(classType, 1), 0);
newVal = Array.get(Creator.newArray(classType, 1), 0);
}
Object oldVal = null;
if (element.listener != null) {

View File

@@ -124,7 +124,7 @@ public abstract class TypeToken<T> {
return null;
}
if (type instanceof GenericArrayType) {
return Array.newInstance(typeToClass(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
return Creator.newArray(typeToClass(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
}
if (!(type instanceof ParameterizedType)) {
return null; //只能是null了
@@ -147,6 +147,30 @@ public abstract class TypeToken<T> {
}
return newTypes;
}
public static Class primitiveToWrapper(Class clazz) {
if (clazz == boolean.class) {
return Boolean.class;
} else if (clazz == byte.class) {
return Byte.class;
} else if (clazz == char.class) {
return Character.class;
} else if (clazz == short.class) {
return Short.class;
} else if (clazz == int.class) {
return Integer.class;
} else if (clazz == float.class) {
return Float.class;
} else if (clazz == long.class) {
return Long.class;
} else if (clazz == double.class) {
return Double.class;
} else if (clazz == void.class) {
return Void.class;
} else {
return clazz;
}
}
//
// public static void main(String[] args) throws Throwable {
// Method tt0 = C.class.getMethod("getValue");

View File

@@ -601,7 +601,7 @@ public final class Utility {
if (array == null || array.length == 0) {
return objs;
}
final T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + objs.length);
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.length);
System.arraycopy(objs, 0, news, 0, objs.length);
System.arraycopy(array, 0, news, objs.length, array.length);
return news;
@@ -631,10 +631,10 @@ public final class Utility {
if (one == null) {
return array;
}
T[] news = (T[]) Array.newInstance(one.getClass(), objs.size());
T[] news = (T[]) Creator.newArray(one.getClass(), objs.size());
return objs.toArray(news);
}
T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + objs.size());
T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.size());
int index = -1;
for (T t : objs) {
news[(++index)] = t;
@@ -1124,7 +1124,7 @@ public final class Utility {
if (objs == null || objs.length == 0) {
return array;
}
final T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + objs.length);
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.length);
System.arraycopy(array, 0, news, 0, array.length);
System.arraycopy(objs, 0, news, array.length, objs.length);
return news;
@@ -1176,10 +1176,10 @@ public final class Utility {
if (one == null) {
return array;
}
T[] news = (T[]) Array.newInstance(one.getClass(), objs.size());
T[] news = (T[]) Creator.newArray(one.getClass(), objs.size());
return objs.toArray(news);
}
T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + objs.size());
T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length + objs.size());
System.arraycopy(array, 0, news, 0, array.length);
int index = -1;
for (T t : objs) {
@@ -1242,7 +1242,7 @@ public final class Utility {
if (array == null || array.length == 0 || filter == null) {
return array;
}
final T[] news = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length);
final T[] news = (T[]) Creator.newArray(array.getClass().getComponentType(), array.length);
int index = 0;
for (int i = 0; i < news.length; i++) {
if (!filter.test(array[i])) {
@@ -1252,7 +1252,7 @@ public final class Utility {
if (index == array.length) {
return array;
}
final T[] rs = (T[]) Array.newInstance(array.getClass().getComponentType(), index);
final T[] rs = (T[]) Creator.newArray(array.getClass().getComponentType(), index);
System.arraycopy(news, 0, rs, 0, index);
return rs;
}