栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何提高Field.set的性能(也许使用MethodHandles)?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何提高Field.set的性能(也许使用MethodHandles)?

2015-06-01:已更新,以反映@JoeC对句柄为静态的另一种情况的评论。 还更新为最新的JMH,并在现代硬件上重新运行。结论几乎保持不变。

请进行适当的基准测试,对于JMH来说并不是很难。一旦这样做,答案就显而易见了。它还可以展示的正确用法

invokeExact
(需要目标/源1.7进行编译和运行):

@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)@Fork(3)@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.NANOSECONDS)@State(Scope.Thread)public class MHOpto {    private int value = 42;    private static final Field static_reflective;    private static final MethodHandle static_unreflect;    private static final MethodHandle static_mh;    private static Field reflective;    private static MethodHandle unreflect;    private static MethodHandle mh;    // We would normally use @Setup, but we need to initialize "static final" fields here...    static {        try { reflective = MHOpto.class.getDeclaredField("value"); unreflect = MethodHandles.lookup().unreflectGetter(reflective); mh = MethodHandles.lookup().findGetter(MHOpto.class, "value", int.class); static_reflective = reflective; static_unreflect = unreflect; static_mh = mh;        } catch (IllegalAccessException | NoSuchFieldException e) { throw new IllegalStateException(e);        }    }    @Benchmark    public int plain() {        return value;    }    @Benchmark    public int dynamic_reflect() throws InvocationTargetException, IllegalAccessException {        return (int) reflective.get(this);    }    @Benchmark    public int dynamic_unreflect_invoke() throws Throwable {        return (int) unreflect.invoke(this);    }    @Benchmark    public int dynamic_unreflect_invokeExact() throws Throwable {        return (int) unreflect.invokeExact(this);    }    @Benchmark    public int dynamic_mh_invoke() throws Throwable {        return (int) mh.invoke(this);    }    @Benchmark    public int dynamic_mh_invokeExact() throws Throwable {        return (int) mh.invokeExact(this);    }    @Benchmark    public int static_reflect() throws InvocationTargetException, IllegalAccessException {        return (int) static_reflective.get(this);    }    @Benchmark    public int static_unreflect_invoke() throws Throwable {        return (int) static_unreflect.invoke(this);    }    @Benchmark    public int static_unreflect_invokeExact() throws Throwable {        return (int) static_unreflect.invokeExact(this);    }    @Benchmark    public int static_mh_invoke() throws Throwable {        return (int) static_mh.invoke(this);    }    @Benchmark    public int static_mh_invokeExact() throws Throwable {        return (int) static_mh.invokeExact(this);    }}

在1x4x2 i7-4790K,JDK 8u40,Linux x86_64上产生:

Benchmark       Mode  Cnt  Score   Error  UnitsMHOpto.dynamic_mh_invoke   avgt   25  4.393 ± 0.003  ns/opMHOpto.dynamic_mh_invokeExact         avgt   25  4.394 ± 0.007  ns/opMHOpto.dynamic_reflect     avgt   25  5.230 ± 0.020  ns/opMHOpto.dynamic_unreflect_invoke       avgt   25  4.404 ± 0.023  ns/opMHOpto.dynamic_unreflect_invokeExact  avgt   25  4.397 ± 0.014  ns/opMHOpto.plain    avgt   25  1.858 ± 0.002  ns/opMHOpto.static_mh_invoke    avgt   25  1.862 ± 0.015  ns/opMHOpto.static_mh_invokeExact          avgt   25  1.859 ± 0.002  ns/opMHOpto.static_reflect      avgt   25  4.274 ± 0.011  ns/opMHOpto.static_unreflect_invoke        avgt   25  1.859 ± 0.002  ns/opMHOpto.static_unreflect_invokeExact   avgt   25  1.858 ± 0.002  ns/op

…这表明在这种特定情况下,MH实际上比反射快得多(这是因为针对私有字段的访问检查是在查找时而不是在调用时完成的)。

dynamic_*
情况模拟了当
MethodHandles
和/或
Fields
不是静态已知(例如从中拉出
Map<String,MethodHandle>
或类似的东西)时的情况。相反,
static_*
情况是调用程序是静态已知的。

请注意,在

dynamic_*
某些情况下,反射性能与MethodHandles相当,这是因为反射在JDK
8中得到了进一步的优化(因为实际上,您不需要访问检查即可读取自己的字段),因此答案可能是“公正”切换到JDK 8;)

static_*
案例甚至更快,因为
MethoHandles.invoke
调用被积极地内联。这消除了MH情况下的部分类型检查。但是,在反思的情况下,仍然存在快速检查,因此,它落后了。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486842.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号