我有很多方法的旧代码,long[] toLongArray(int[] array)但是对于许多不同的原始类型配置(在两侧),我只是想知道是否有可能为此创建一个通用方法而又不损失性能。
首先,我使用MethodHandles为int []-> long []对创建了简单的方法:
static final MethodHandle getIntElement = MethodHandles.arrayElementGetter(int[].class);
static final MethodHandle setLongElement = MethodHandles.arrayElementSetter(long[].class);
static long[] specializedMethodHandle(int[] array) throws Throwable {
long[] newArray = new long[array.length];
for (int i = 0; i < array.length; i++) getIntElement.invokeExact(newArray, i, (long) (int) setLongElement.invokeExact(array, i));
return newArray;
}
而且效果很好-与手动循环的性能相同,因此我决定采用以下通用名称:
static Map<Class<?>, MethodHandle> metHanGettersObj = Map.of(int[].class, MethodHandles.arrayElementGetter(int[].class).asType(MethodType.methodType(Object.class, Object.class, int.class)));
static Map<Class<?>, MethodHandle> metHanSettersObj = Map.of(long[].class, MethodHandles.arrayElementSetter(long[].class).asType(MethodType.methodType(void.class, Object.class, int.class, Object.class)));
static <F, T> T genericMethodHandleObject(Class<T> to, F array) throws Throwable {
int length = Array.getLength(array);
Object newArray = Array.newInstance(to.getComponentType(), length);
MethodHandle getElement = metHanGettersObj.get(array.getClass());
MethodHandle setElement = metHanSettersObj.get(to);
for (int i = 0; i < length; i++) setElement.invokeExact(newArray, i, getElement.invokeExact(array, i));
return (T) newArray;
}
但这要慢得多,对于我的500000个元素的示例数组,它慢了15倍以上。
用Nashorn javascript引擎制作的有趣的CompiledScript比此代码快20%左右。(内部的简单复制循环)
所以我想知道是否有人知道这样做的其他方式?我可能不会在任何地方使用它,因为它开始变得太“ hacky”了,但是现在我只需要知道是否有可能-因为没有带有方法句柄的通用方法可以正常工作,所以为什么这个方法这么慢,并且有可能使它更快吗?
波斯汪
随时随地看视频慕课网APP
相关分类