相关疑难解决方法(0)

如何提高Field.set的性能(使用MethodHandles进行perhap)?

我正在写一些调用的代码Field.setField.get数千次.显然,由于反射,这是非常缓慢的.

我想看看我是否可以MethodHandle在Java7中提高性能.到目前为止,这就是我所拥有的:

而不是field.set(pojo, value),我正在做:

private static final Map<Field, MethodHandle> setHandles = new HashMap<>();

MethodHandle mh = setHandles.get(field);
if (mh == null) {
    mh = lookup.unreflectSetter(field);
    setHandles.put(field, mh);
}
mh.invoke(pojo, value);
Run Code Online (Sandbox Code Playgroud)

但是,这似乎没有比使用反射的Field.set调用更好.我在这里做错了吗?

我读到使用invokeExact可能会更快,但当我尝试使用它时,我得到了一个java.lang.invoke.WrongMethodTypeException

有没有人成功地优化了对Field.set或Field.get的重复调用?

java reflection performance field methodhandle

38
推荐指数
4
解决办法
6262
查看次数

LambdaMetafactory的Java访问bean方法

我的问题与 该线程中显式使用LambdaMetafactory密切相关,提供了一些非常好的例子来使用LambdaMetafactory访问类的静态方法; 但是,我想知道访问现有bean实例的非静态字段的等效代码是什么.似乎很难找到一个例子,我所执行的每一次尝试都以非工作代码结束.

这是bean代码:

class SimpleBean {
    private Object obj= "myCustomObject";
    private static Object STATIC_OBJECT = "myCustomStaticObject";
    public Object getObj() {
        return obj;
    }
    public void setObj(final Object obj) {
        this.obj = obj;
    }
    public static Object getStaticObj() {
        return STATIC_OBJECT;
    }
    public static void setStaticObj(final Object obj) {
        STATIC_OBJECT = obj;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里是一个成功访问静态方法"getStaticObj()"的工作单元测试:

    @Test
public void accessStaticMethod() throws Throwable
{
    MethodHandles.Lookup caller = MethodHandles.lookup();
    Method reflected = SimpleBean.class.getDeclaredMethod("getStaticObj");
    MethodHandle methodHandle = caller.unreflect(reflected);
    CallSite site = LambdaMetafactory.metafactory(caller, …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8

13
推荐指数
1
解决办法
4277
查看次数

如何使用LambdaMetaFactory调用构造函数?

我想尝试避免反射调用构造函数,并尝试遵循本文中采用的LamdaMetaFactory方法 - 更快地替代Java的反射

我想要构建的类看起来像:

interface DBBroker {}

public class NativeBroker implements DBBroker {
    public NativeBroker(BrokerPool brokerPool, final Configuration configuration) {
    }
}
Run Code Online (Sandbox Code Playgroud)

使用LambaMetaFactory我试图构造一个BiFunction<BrokerPool, Configuration, DBBroker>替换直接调用构造函数.

到目前为止我的代码看起来像:

Class<? extends DBBroker> clazz =
    (Class<? extends DBBroker>) Class.forName("org.exist.storage.NativeBroker");

MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh =
    lookup.findConstructor(clazz, MethodType.methodType(void.class, new Class[] {BrokerPool.class, Configuration.class}));

BiFunction<BrokerPool, Configuration, DBBroker> constructor 
    (BiFunction<BrokerPool, Configuration, DBBroker>)
        LambdaMetafactory.metafactory(
                    lookup, "apply", MethodType.methodType(BiFunction.class),
                    mh.type(), mh, mh.type()).getTarget().invokeExact();

final DBBroker broker = constructor.apply(database, conf);
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会返回错误 -

AbstractMethodError:方法org/exists/storage/BrokerFactory $$ Lambda $ 55.apply(Ljava/lang/Object; Ljava/lang/Object;)Ljava/lang/Object; …

java lambda invokedynamic java-8

9
推荐指数
1
解决办法
370
查看次数

MethodHandles还是LambdaMetafactory?

在我的工作中,我们有一个用于指定数学公式的DSL,我们后来应用于很多点(数百万).

截至今天,我们构建公式的AST,并访问每个节点以产生我们称之为"评估者"的东西.然后,我们向该求值程序传递公式的参数,并为每个点进行计算.

例如,我们有这个公式: x * (3 + y)

           ??????
     ???????mult???????
     ?     ??????     ?
     ?                ?
  ???v???          ???v???
  ?  x  ?      ????? add ????
  ???????      ?   ???????  ?
               ?            ?
            ???v???      ???v???
            ?  3  ?      ?  y  ?
            ???????      ???????
Run Code Online (Sandbox Code Playgroud)

我们的评估员将为每个步骤发出"评估"对象.

这种方法易于编程,但效率不高.

所以我开始研究方法句柄来构建一个"组合"的方法句柄,以加快最近的速度.

这样的事情:我有我的"算术"课:

public class Arithmetics {

  public static double add(double a, double b){
      return a+b;
  }

  public static double mult(double a, double b){
      return a*b;
  }

}
Run Code Online (Sandbox Code Playgroud)

在构建我的AST时,我使用MethodHandles.lookup()来直接获取它们的句柄并组合它们.沿着这些方向的东西,但在一棵树上:

Method add = ArithmeticOperator.class.getDeclaredMethod("add", double.class, double.class);
Method mult = ArithmeticOperator.class.getDeclaredMethod("mult", double.class, …
Run Code Online (Sandbox Code Playgroud)

java lambda invokedynamic java-8 methodhandle

8
推荐指数
1
解决办法
728
查看次数

是否有可能使java.lang.invoke.MethodHandle与直接调用一样快?

我正在比较性能MethodHandle::invoke和直接静态方法调用.这是静态方法:

public class IntSum {
    public static int sum(int a, int b){
        return a + b;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的基准:

@State(Scope.Benchmark)
public class MyBenchmark {

    public int first;
    public int second;
    public final MethodHandle mhh;

    @Benchmark
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @BenchmarkMode(Mode.AverageTime)
    public int directMethodCall() {
        return IntSum.sum(first, second);
    }

    @Benchmark
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @BenchmarkMode(Mode.AverageTime)
    public int finalMethodHandle() throws Throwable {
        return (int) mhh.invoke(first, second);
    }

    public MyBenchmark() {
        MethodHandle mhhh = null;

        try {
            mhhh = MethodHandles.lookup().findStatic(IntSum.class, "sum", MethodType.methodType(int.class, int.class, int.class));
        } catch (NoSuchMethodException …
Run Code Online (Sandbox Code Playgroud)

java performance jit jvm jmh

8
推荐指数
2
解决办法
649
查看次数

如何为字段创建功能接口实现?

考虑weightclass 中的一个字段Animal。我希望能够创建用于操作此字段的gettersetter功能接口对象。

class Animal {
  int weight;
}
Run Code Online (Sandbox Code Playgroud)

我目前的方法类似于用于方法的方法:

public static Supplier getter(Object obj, Class<?> cls, Field f) throws Exception {
  boolean isstatic = Modifier.isStatic(f.getModifiers());
  MethodType sSig = MethodType.methodType(f.getType());
  Class<?> dCls = Supplier.class;
  MethodType dSig = MethodType.methodType(Object.class);
  String dMthd = "get";
  MethodType dType = isstatic? MethodType.methodType(dCls) : MethodType.methodType(dCls, cls);
  MethodHandles.Lookup lookup = MethodHandles.lookup();
  MethodHandle fctry = LambdaMetafactory.metafactory(lookup, dMthd, dType, dSig, lookup.unreflectGetter(f), sSig).getTarget();
  fctry = !isstatic && obj!=null? fctry.bindTo(obj) : fctry;
  return (Supplier)fctry.invoke(); …
Run Code Online (Sandbox Code Playgroud)

java reflection java-8

4
推荐指数
2
解决办法
5372
查看次数

标签 统计

java ×6

java-8 ×4

lambda ×3

invokedynamic ×2

methodhandle ×2

performance ×2

reflection ×2

field ×1

jit ×1

jmh ×1

jvm ×1