乔纳森,深入分析您的案例,您的性能问题的答案来自多种因素。让我一一解释:
- 装箱/拆箱- 这确实对您的结果产生了影响,正如在这个线程中回答的那样,如何避免在 javanet 中对数组中的基元进行自动装箱有 beta 版本,其中包括强制 Javonet 使用原始数组作为结果的能力。所以这个问题很容易解决。
- 此处提到的不必要的字符串传递Java 开发人员的 Javonet当前版本的性能仍然存在一个问题,即使对于优化的后续方法调用,方法名称也被传递到 .NET 端并转换为 .NET 字符串。此外,对于每个结果,类型名称都会返回并转换为 Java 字符串。这已经在 Javonet 中为 .NET 开发人员解决了。我们在临时构建中为您解决了这个问题,将这些优化合并到 Java 开发人员的 Javonet 中。(下方链接)。
- 数据类型转换分析您的结果,我们发现“双重”处理中的一个问题可能会影响您的性能。这也包含在下面链接的临时构建中。
- Javonet 的操作类型最昂贵的操作是值类型的动态转换。根据时间的不同,它要么是超快的(即布尔值),要么是相当昂贵的(即 UInt64)。因此,您的情况很特殊,因为您进行的跨界调用很少,但您进行了大量的值类型转换(2GB 的数组)。如果您比较多次调用(即 250k)方法为增长的“x”参数生成素数,您应该观察到完全不同的结果。(如果您将其与通过 Web 服务调用相同的方法进行比较,我将快 1000 倍)
- 比较结果的方式最后但非常重要的是,Javonet 的性能取决于您执行的操作和比较结果的方式。很明显,如果您调用一个纯粹在 .NET 中什么都不做的方法,它将由编译器优化并几乎“立即”执行。当您通过 Javonet 调用它时,将需要一些“微小”时间(即 0.0000009 秒)将调用传递给 .NET。结果,当您将“微小”除以“无时间”时,就像将 10 除以 0,因此您可以假设它无限慢(这是否意味着 Javonet 很慢? - 不完全是)。但是,如果您调用一个方法来执行某些处理或从 DB 等检索数据。那么 Javonet 开销几乎不会引起注意。
不稳定的 beta 版本,修复了错误的字符串交换和双重数据类型转换:
...链接因以下更新中包含的较新版本而被删除...
请仅将其用于测量目的。我们很高兴知道您的结果。很快,这些更改将以稳定状态合并到正式版本中,我们会在之后通知您。
总结:您获得的性能结果有不同的原因。其中一些正在通过上面提到的 beta 补丁解决,一些与您的测量和操作方式有关。在许多情况下,Javonet 是 .NET 和 Java 之间最快的本机集成技术,在我们的许多客户的测试中得到认可,并且在高频交易、实时数据处理、控制制造和医疗设备等解决方案中受到信任... 当然,仍然存在性能变化的情况和案例。实现最高结果是我们的主要优先事项之一,遵循我们的一项原则“每次发布都更快”。如果需要,我们始终接受客户实施按需改进的性能挑战。我们确实接受您的,并将努力优化大型原始数组检索。
请测试上面应该有显着改进但仍会受到环境原因影响的补丁:4 和 5。
2018 年 4 月 30 日更新:我们已经开始实施现代化优化模块,以解决像您这样的场景,保持几乎与原生相同的最高性能。在下面的链接下,您会发现 alpha 版本适用于“usePrimitiveArraysMode”,用于返回“double []”而不带 ref/out 参数的非泛型方法。即 double[] CreateArray() 或 double[] CreateArray(int size) 等...
http://download.javonet.com/1.5/javonet-1.5hf15-primitivearrays-opti-jtdn.jar