0

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

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

此外,Javonet 是否“智能”足以将整个数组(原语)复制到“Java VM 的内存/堆栈”中,以便当我尝试访问(非常大,大约 2GB 数组)中的每个元素时,它不会尝试为每个元素访问执行 JNI 调用?

最后,一般来说,在我上面的场景中,Javonet 会(实质上)比 jni4net 或 jnbridgePro 快/慢(一个大小为 1000 万的循环和包含大约 2GB 原始浮点数的原语数组),是否有任何理论(或观察到的)原因)?

4

1 回答 1

1

感谢您的好评!

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

旁注: 目前在面向 Java 开发人员的 Javonet 中,您的字符串方法名称仍会传递给 .NET 端(甚至未在进一步调用中使用),这可能会影响性能,但我们已经在面向 .NET 开发人员的 Javonet 中对其进行了优化。请通过电子邮件联系 Javonet 支持以获取包含在产品 Java 版本中的优化的非官方构建。

如果您检索原始数组, Javonet 将在一次调用中返回整个数组,因此您可以进一步将其用作纯 Java 数组,而无需任何回调到 .NET 端。Javonet 还能够返回混合数组,其中一些项目是基元(转换为 Java 类型),一些是在最终 Java Object[]中显示为NObject实例的类。

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

总结 Javonet 实际上在执行期间动态构建了固定包装器。为了语法可用性,您可以使用强类型接口包装您的类,并通过 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);
     }
}

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

于 2018-04-27T13:44:35.727 回答