不确定这是否是正确的地方。在我的案例中,我注意到在YourKit中(但任何其他探查器都会做)Native.setShort的巨大贡献。这将在Structure中设置字段以填充jna库调用参数。 SetShort在jna lib代理调用下面调用了大约10个级别。实际的函数调用windows' kernel32.dll根本没有出现在采样中。返回值时,任何Structure.read活动都没有。
现在,我查看了这个和其他原始值设置器的作用:它们获取参数的地址,并通过memcpy或bcopy将sizeof(参数)字节移动到目标地址,可能包含在try / catch宏中。为什么这样做?为什么不是这样的:
*((short*) target) = value
这会更有效还是try / catch在这里很重要?周围的PSTART / PEND宏似乎并不总是生成try / catch。 这是来自git的最新JNA抓取4.2.0。
更新:看起来这是个人在我身上开玩笑。今天,我看到浪费的时间更均匀地分散在实际原生呼叫的其他调用堆栈级别中。
我的解决方案是使用JNA直接映射:在我自己的DLL中添加另一个函数在OS API之上,它使用原始指针而不是Structure.ByReference
来返回值。对每个返回参数使用单元素基本数组调用此函数需要370 ns和1500 ns(不包括new Structure.ByReference()
)。
因此,最后,Native.setXXX()方法实际上很慢,并且所有粘合代码都围绕JNA方法调用。但是JNA直接映射可以做到这一点。我从未测试过实际的JNI呼叫,所以无法比较这里的时间。
答案 0 :(得分:2)
在* nix系统上,Private Sub Bold_Text(rtBox As RichTextBox)
Dim newStyle As FontStyle
If InStr(rtBox.SelectionFont.Style.ToString, "Bold") Then 'Changed this line to search the string
newStyle = rtBox.SelectionFont.Style And Not FontStyle.Bold
Else
newStyle = rtBox.SelectionFont.Style Or FontStyle.Bold
End If
Dim newFont As New Font(rtBox.SelectionFont.Name, rtBox.SelectionFont.Size, newStyle)
rtBox.SelectionFont = newFont
End Sub
/ PSTART
执行PEND
/ setjmp
以捕获一系列内存错误(但仅限于longjmp
)。在Windows上,它使用结构化异常处理(基本上Native.setProtected(true)
/ try
)来执行相同的操作,并且默认情况下处于启用状态。
即使启用,与JNI转换本身的开销相比,它们也不太可能增加很多开销(从Java到C,反之亦然)。
通常,将catch
传递给本机代码并不是非常有效,因为自动写入和读取很大程度上依赖于将Java字段复制到本机内存中的反射。但在大多数情况下,这并不重要。
对于发现瓶颈的少数情况,您需要使用JNA的直接映射并将自己限制为原始参数。