// mydll.c
__declspec(dllexport) double test(double a, double b)
{
return a / b - 1;
}
// test.java
import com.sun.jna.Native;
import com.sun.jna.Library;
public class test {
public interface DLL extends Library {
DLL INSTANCE = (DLL)Native.load("mydll", DLL.class);
double test(double a, double b);
}
public static void main(String[] args) {
DLL dll = DLL.INSTANCE;
long st = System.nanoTime();
dll._conformance(3.234, 4.234);
System.out.println("耗时: " + String.valueOf(System.nanoTime() - st));
}
}
// 耗时: 6795340
import time
from ctypes import *
dll = CDLL("mydll.dll")
dll.test.restype = c_double
def invoke():
st = time.time_ns()
dll.test(c_double(3.234), c_double(4.234))
print("耗时: ", time.time_ns() - st)
invoke()
# 耗时: 0
为什么 jna 调用一次 dll函数,都是 毫秒级的?怎么样能达到 python 那样的调用速度?
JNA 调用 dll 函数是毫秒级的,这主要是因为它将调用转换为 Java Native Interface (JNI)调用,以帮助实现编程语言之间的互操作性。它将功能转换成,当调用dll函数时,它会将操作放入JNI调用并完成,从而大大缩短了调用时间。
要达到与Python一样的调用速度,需要采用类似JNI这样的库,以帮助提高调用速度。此外,可以考虑使用多线程来调用dll函数,充分利用CPU的资源,以便更好地使用现有计算机资源,进一步提高调用速度。
你试试通过接口去调用,感觉你这样写是不是要先去加载库函数,没有加载到缓存里面,这个时间是计算了加载JNI库函数的时间
// JNITest.java
public class JNITest {
static {
System.loadLibrary("mydllJNI");
}
public native double test(double a , double b);
};
// test.java
import com.sun.jna.Native;
import com.sun.jna.Library;
public class test {
public interface DLL extends Library {
DLL INSTANCE = (DLL)Native.load("mydll", DLL.class);
double test(double a, double b);
}
public static void main(String[] args) {
DLL dll = DLL.INSTANCE;
JNITest jt = new JNITest();
long st, et;
for (int i = 0; i < 10; i++) {
st = System.nanoTime();
dll.test(3.234, 4.234);
et = System.nanoTime();
System.out.println(i + "次耗时: " + (et - st));
}
for (int i = 0; i < 10; i++) {
st = System.nanoTime();
jt.test(3.234, 4.234);
et = System.nanoTime();
System.out.println(i + "次耗时: " + (et - st));
}
}
}
次数 | JNA耗时(ns) | JNI耗时(ns) |
---|---|---|
第1次调用 | 6471263 | 4976 |
第2次调用 | 28924 | 623 |
第3次调用 | 23948 | 622 |
第4次调用 | 42919 | 311 |
第5次调用 | 18972 | 311 |
第6次调用 | 14618 | 622 |
第7次调用 | 14929 | 623 |
第8次调用 | 14306 | 311 |
第9次调用 | 14618 | 311 |
第10次调用 | 14618 | 311 |