为了账号安全,请及时绑定邮箱和手机立即绑定

转换基本数组的通用方法

转换基本数组的通用方法

波斯汪 2021-03-30 16:15:55
我有很多方法的旧代码,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”了,但是现在我只需要知道是否有可能-因为没有带有方法句柄的通用方法可以正常工作,所以为什么这个方法这么慢,并且有可能使它更快吗?
查看完整描述

1 回答

  • 1 回答
  • 0 关注
  • 156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信