0

在另一篇文章中,我谈到了在 javonet 中支持原始数组的必要性。这可以解释为什么拉动约 2GB 的双数组比 .net 中的可比代码慢约 10 倍吗?我附上了 JProfiler 的屏幕截图以防万一。(此外,虽然没有显示,JProfiler 还显示了大约 1GB 的 Double 对象,如果我们只有原语,我认为它们不应该存在;但是,这是缓慢的原因还是因为对 .net 的约 40,000 次调用方法,以及与 Javonet 等之间的所有“东西”最终需要几百毫秒左右?)

JProfiler 主机点视图

2018 年 5 月 3 日更新:

如果您阅读对第一个响应的评论,您最终会看到一个解决缓慢问题的构建 (hf16)。Javonet 出现得相当快……我想这个构建最终会成为核心产品。

4

1 回答 1

0

乔纳森,深入分析您的案例,您的性能问题的答案来自多种因素。让我一一解释:

  1. 装箱/拆箱- 这确实对您的结果产生了影响,正如在这个线程中回答的那样,如何避免在 javanet 中对数组中的基元进行自动装箱有 beta 版本,其中包括强制 Javonet 使用原始数组作为结果的能力。所以这个问题很容易解决。
  2. 此处提到的不必要的字符串传递Java 开发人员的 Javonet当前版本的性能仍然存在一个问题,即使对于优化的后续方法调用,方法名称也被传递到 .NET 端并转换为 .NET 字符串。此外,对于每个结果,类型名称都会返回并转换为 Java 字符串。这已经在 J​​avonet 中为 .NET 开发人员解决了。我们在临时构建中为您解决了这个问题,将这些优化合并到 Java 开发人员的 Javonet 中。(下方链接)。
  3. 数据类型转换分析您的结果,我们发现“双重”处理中的一个问题可能会影响您的性能。这也包含在下面链接的临时构建中。
  4. Javonet 的操作类型最昂贵的操作是值类型的动态转换。根据时间的不同,它要么是超快的(即布尔值),要么是相当昂贵的(即 UInt64)。因此,您的情况很特殊,因为您进行的跨界调用很少,但您进行了大量的值类型转换(2GB 的数组)。如果您比较多次调用(即 250k)方法为增长的“x”参数生成素数,您应该观察到完全不同的结果。(如果您将其与通过 Web 服务调用相同的方法进行比较,我将快 1000 倍)
  5. 比较结果的方式最后但非常重要的是,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

于 2018-04-28T23:02:27.223 回答