Javonet 的性能

Performance of Javonet

到目前为止,我已经让 Javonet 调用 .net dll。创建 javonet 代码就像宣传的那样简单。

但是,在我的例子中,我有一个运行大约 1000 万次的循环,在该循环中,我通过 Javonet 调用一个 dll 方法。我的问题是:因为我似乎将方法名称作为字符串传递给 Javonet(基于 javonet 的做事方式),我假设 Javonet 使用某种反射来找到相应的 dll 方法......但是不会'这会很慢(当处于 1000 万循环中时),特别是因为我们已经为 javonet 注册了大约十几个不同的 dll(或者比 jni4net 和 jnbridge 等解决方案慢,它们似乎生成实际代理,允许我在我的 java 代码 dll 方法命名自己而不将方法名称作为字符串传递?)

此外,Javonet "smart" 是否足以将整个数组(原语)复制到 "Java VM's memory/stack" 中,这样当我尝试访问(非常大,大约 2GB 的数组)中的每个元素时它不会尝试为每个元素访问执行 JNI 调用?

最后,总的来说,在我上面的场景(大小为 1000 万的循环和基元数组包含大约 2GB 的原始浮点数)?

感谢您的好评!

Javanet 不会对您的 1000 万次调用中的每一次进行反射调用,我们确实会在第一次扫描类型,但所有后续调用都是针对指向目标方法的固定指针完成的。

旁注: 目前在 Javonet 中,对于 Java 开发人员,您的字符串方法名称仍然传递给 .NET 端(甚至没有在进一步使用调用)什么会影响性能,但我们已经在 J​​avonet 中为 .NET 开发人员优化了它。请通过电子邮件联系 Javonet 支持,以获得包含在产品 Java 版本中的优化的非官方版本。

如果您检索原语数组 Javonet 将在一次调用中return 整个数组,因此您可以将它作为纯Java 数组进一步使用而无需任何调用回到.NET 端。 Javonet 还能够 return 混合数组,其中一些项是原始类型(转换为 java 类型),一些是 classes,显示为 NObject final Java Object[].

中的实例

我们有意更喜欢 JIT 生成的包装器和我们的反射样式 API 而不是预生成的包装器,以提供使用 Javonet 的最大灵活性。因此开发人员可以自行决定如何使用目标库,如何优化代码以最大限度地减少跨界调用。此外,无需安装任何工具或扩展程序或 运行 任何应用程序即可通过 Javonet 使用 .NET DLL。我们的目标是确保您下载单个文件并在前 5 分钟内使用来自 Java 的任何 .NET 代码。

总结 Javonet 实际上在执行过程中即时构建固定包装器。对于语法可用性,您可以使用强类型接口包装 class 并通过 Javonet API 在内部路由调用。第一次调用后,您的路由将得到优化,每次调用平均应执行百万分之九秒。如果您有更高的需求,请告诉我们,我们很乐意满足您的要求!

包装示例可能如下所示:

class Car {
     private NObject handle;

     public Car() throws JavonetException {
         handle = Javonet.New(Car.class.getName());
     }

     public void increaseSpeed(int newSpeed) {
         handle.invoke("startEngine", newSpeed);
     }
     public void addPassenger(Passenger person) {
         handle.invoke("addPassenger", person);
     }
}
class Passenger {
     private NObject handle; 

     public Passenger(String name) {
         handle = Javonet.New(Passenger.class.getName(),name);
     }
}

请注意私有 "handle" 字段。如果您在激活 Javonet 之前调用 Javonet.setUsePrivateHandleField(bool value)。当您将带有私有句柄字段 Javonet 作为任何 .NET 方法的参数传递此类 class 的实例时,Javonet 将使用正确的 .NET 实例。