JNA、JNI、原生C++函数调用效率及测试过程

结论

  1. 如果JAVA要高效调用C++函数,则需要通过JNI封装C++函数后进行native方法调用,JNI的执行效率比JNA高600倍左右。
  2. 从开发效率上来说,JNA开发速度比JNI快许多,因为不需要做二次封装

测试对比

纯C++调用:
Function call took 6700 ns => 0.0067ms

JAVA JNI调用:
Time taken to get version: 515801 ns => 0.515ms

JAVA JNA调用:
Time taken to get version: 333768699 ns => 333.76786ms

原生C++调用验证

1.Visual Studio配置头文件及lib库文件的路径
在这里插入图片描述
在这里插入图片描述
2.添加附加依赖库
在这里插入图片描述
3.调用函数计算时长

#include <iostream>
#include <chrono>
#include <iomanip> 
#include "AlgInterface.h"
using namespace std::chrono;int main()
{high_resolution_clock::time_point start = high_resolution_clock::now();int version[4] = { 0 };GetAlgVersion(version);// 结束时间点high_resolution_clock::time_point end = high_resolution_clock::now();// 计算耗时std::chrono::nanoseconds duration = end - start;// 打印结果和耗时std::cout << "Function call took " << duration.count() << "ns\n";std::string versionStr = std::to_string(version[0]) + "." + std::to_string(version[1]) + "." + std::to_string(version[2]) + "." + std::to_string(version[3]);std::cout << versionStr << "\n";return 0;
}

JAVA JNI调用

1.定义JNI方法

public class EcgJniLib {public static native String getVersion(int[] version);
}

2.生成.h头文件,用于包装C++方法
可以简单写个BAT在需要生成JNI的同级目录
在这里插入图片描述

> javac D:\WorkSpace\jni\EcgJniLib.java
> javac -h D:\WorkSpace\jni\ D:\WorkSpace\jni\EcgJniLib.java

此时会生成.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_cloud_ecgstats_jni_EcgJniLib */#ifndef _Included_com_cloud_ecgstats_jni_EcgJniLib
#define _Included_com_cloud_ecgstats_jni_EcgJniLib
#ifdef __cplusplus
extern "C" {
#endif
/** Class:     com_cloud_ecgstats_jni_EcgJniLib* Method:    getVersion* Signature: ([I)Ljava/lang/String;*/
JNIEXPORT jstring JNICALL Java_com_cloud_ecgstats_jni_EcgJniLib_getVersion(JNIEnv *, jclass, jintArray);#ifdef __cplusplus
}
#endif
#endif

3.通过Clion封装C++函数
创建动态库
在这里插入图片描述
拷贝.h文件,并创建cpp文件
在这里插入图片描述
配置cmakelist文件

cmake_minimum_required(VERSION 3.17)
project(jniWrapper)set(CMAKE_CXX_STANDARD 11)#定义头文件需要寻址的路径
include_directories("C:\\EcgAlgo""D:\\Library\\jdk-11.0.15\\include""D:\\Library\\jdk-11.0.15\\include\\win32"
)
#定义库文件需要寻址的路径
link_directories("C:\\EcgAlgo"
)add_library(jniWrapper SHARED library.cpp com_cloud_ecgstats_jni_EcgJniLib.cpp)
target_link_libraries(jniWrapperAlgInterface
)

4.封装执行函数

#include <AlgInterface.h>
#include "com_cloud_ecgstats_jni_EcgJniLib.h"JNIEXPORT jstring JNICALL Java_com_cloud_ecgstats_jni_EcgJniLib_getVersion(JNIEnv* env, jclass, jintArray)
{int version[4];GetAlgVersion(version);std::string versionStr;versionStr = std::to_string(version[0]) + "." + std::to_string(version[1]) + "." + std::to_string(version[2]) + "." + std::to_string(version[3]);jstring jstr = env->NewStringUTF(versionStr.c_str());return jstr;
}

5.构建项目,会生成DLL
在这里插入图片描述
6.将生成的DLL及依赖的算法DLL复制到jdk/bin目录下
在这里插入图片描述
7.java调用JNI函数执行DLL方法

package com.cloud.ecgstats.jni;import org.springframework.util.StopWatch;public class EcgJniLibInstance {static {System.loadLibrary("jniWrapper");}public static void main(String[] args) {System.out.println(System.getProperty("java.library.path"));StopWatch stopWatch = new StopWatch();stopWatch.start();int[] status = new int[4];String version = EcgJniLib.getVersion(status);stopWatch.stop();System.out.println("Time taken to get version: " + (stopWatch.getTotalTimeNanos()) + "ns");System.out.println(version);}
}

JAVA JNA调用

1.构建DLL Library

package com.cloud.ecgstats.jna;import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;public interface EcgLibrary extends Library {EcgLibrary INSTANCE = Native.load(Platform.isWindows() ? "C:\\AlgInterface.dll" : "/usr/lib/libG.so", EcgLibrary.class);void GetAlgVersion(int[] data);
}

2.调用

package com.cloud.ecgstats.jna;import org.springframework.util.StopWatch;import java.util.Arrays;public class EcgLibraryInstance {public void getVersion(){int[] status = new int[4];StopWatch stopWatch = new StopWatch();stopWatch.start();EcgLibrary.INSTANCE.GetAlgVersion(status);stopWatch.stop();System.out.println("Time taken to get version: " + (stopWatch.getTotalTimeNanos() ) + "ns");System.out.println(Arrays.toString(status));}public static void main(String[] args) {EcgLibraryInstance ecgLibraryInstance = new EcgLibraryInstance();ecgLibraryInstance.getVersion();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/802034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入了解iOS内存(WWDC 2018)笔记-内存诊断

主要记录下用于分析iOS/macOS 内存问题的笔记。 主要分析命令&#xff1a; vmmap, leaks, malloc_history 一&#xff1a;前言 有 3 种思考方式 你想看到对象的创建吗&#xff1f;你想要查看内存中引用对象或地址的内容吗&#xff1f;或者你只是想看看 一个实例有多大&#…

【强化学习】Actor-Critic

Actor-Critic算法 欢迎访问Blog全部目录&#xff01; 文章目录 Actor-Critic算法1.Actor-Critic原理1.1.简述1.1.优劣势1.3.策略网络和价值网络1.3.1.策略网络&#xff08;Actor)1.3.2.价值网络&#xff08;Critic) 1.4.程序框图和伪代码 2.算法案例&#xff1a;Pendulum-v12…

T-Mamba:用于牙齿 3D CBCT 分割的频率增强门控长程依赖性

T-Mamba&#xff1a;用于牙齿 3D CBCT 分割的频率增强门控长程依赖性 摘要Introduction方法T-Mamba architectureTim block T-Mamba: Frequency-Enhanced Gated Long-Range Dependendcy for Tooth 3D CBCT Segmentation 摘要 三维成像中的高效牙齿分割对于正畸诊断至关重要&am…

Windows系统读取XDMA实际运行链路速度和PCIE带宽

在我们平常设计XDMA的时候&#xff0c;经常会遇到一个问题&#xff1a; 在Vivado中设计的XDMA IP中选择的PCIE带宽和链路速度是理想的&#xff0c;但是下到板卡运行的时候&#xff0c;测量速度却发现读写速度根本不是理想中的速度&#xff0c;找不到问题&#xff0c;无法证明我…

Octopus:2B 参数语言模型即可媲美 GPT-4 的函数调用性能

近年来&#xff0c;大语言模型在 PC、智能手机和可穿戴设备的操作系统中应用逐渐成为趋势。 例如&#xff0c;MultiOn (Garg, 2024) 和 Adept AI (Luan, 2024) 等 AI 助理工具&#xff0c;以及 Rabbit R1 (Lyu, 2024) 和 Humane AI Pin (Chaudhri, 2024) 等 AI 消费产品在消费者…

蓝桥杯 交通信号 2022研究生组

问题&#xff1a; Dijstra算法变形题&#xff0c;有向边分正行和逆行方向&#xff0c;注意逆行的绿灯时间是正行的红灯时间。 这题的关键是理清从当前节点出发&#xff0c;到下一个节点是哪一时刻&#xff0c;理清这一点后&#xff0c;再跑Dijstra算法求最短路。 假设curr_t时…

JavaScript(三)-Web APIS

文章目录 DOM事件进阶事件流事件流与两个阶段说明事件捕获事件冒泡阻止冒泡解绑事件 事件委托其他事件页面加载事件元素滚动事件页面尺寸事件 元素尺寸与位置 DOM事件进阶 事件流 什么是事件流 事件流指的是事件完整执行过程中的流动路径 事件流与两个阶段说明 捕获与冒泡 …

简介:基于Web的产品3D

基于 Web 的产品 3D 通过可视化界面获得各种选项来个性化他们的产品&#xff0c;例如颜色、材料、尺寸、文字、徽标、零件等。 在过去几年中&#xff0c;随着 3D 建模和渲染软件的出现&#xff0c;3D 渲染现在更常用于营销和促销目的。设计师、制造商和营销人员使用 3D 产品渲…

政安晨:【Keras机器学习实践要点】(二十一)—— MobileViT:基于变换器的移动友好图像分类模型

目录 简介 导入 超参数 MobileViT 实用程序 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; …

AI 创业指难(一) :Stable Diffusion AI 绘画怎么用

一. 前言 一年不到&#xff0c;AI对生活和工作的影响已经逐步体现。所以千万别掉队了&#xff0c;也许 AI 不能成为我们的主要工作&#xff0c;但是如何借助 AI 实现副业的扩展同样值得思考。 这一篇就来讲一个 AI 绘画工具&#xff0c;这个工具我也是才上手不久&#xff0c;…

冻干可以长期给猫咪吃吗?五款顶尖生骨肉冻干盘点推荐

近年来&#xff0c;冻干猫粮因其高品质而备受喜爱&#xff0c;吸引了无数猫主人的目光&#xff0c;像我这样的养猫老手早已开始冻干喂养。但对于新手养猫的人来说&#xff0c;他们可能会对冻干猫粮感到陌生&#xff0c;并产生疑问&#xff1a;这到底是什么&#xff1f;冻干可以…

.NET 设计模式—装饰器模式(Decorator Pattern)

简介 装饰者模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你在不改变对象接口的前提下&#xff0c;动态地将新行为附加到对象上。这种模式是通过创建一个包装&#xff08;或装饰&#xff09;对象&#xff0c;将要被装饰的对象包裹起来…

看看你的身体出现了哪些症状,要当心了!

身体出现以下五个症状&#xff0c;你要小心了。 夜间尿频&#xff0c;不要以为晚上喝水喝多了&#xff0c;很有可能是你的血糖升高了&#xff0c;血糖过高的人&#xff0c;口腔很容易受到刺激&#xff0c;而感到非常的干燥&#xff0c;所以会通过补充水分的方式来缓解&#xff…

基于java+springboot+vue实现的农产品销售系统(文末源码+Lw)23-231

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统乐乐农产品销售系统信息管理难度大&#xff0c;容错率低…

Springboot-redis整合

Springboot-redis命令行封装 前言 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;即远程字典服务&#xff0c;是一个开源的使用ANSI C语言编写的、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。Redis也是现…

CSS导读 (Emmet语法)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 续&#xff1a;七、Chrome调试工具 一、Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 &…

LangChain-10 Agents langchainhub 共享的提示词Prompt

LangChainHub 的思路真的很好&#xff0c;通过Hub的方式将Prompt 共享起来&#xff0c;大家可以通过很方便的手段&#xff0c;短短的几行代码就可以使用共享的Prompt。 我个人非常看好这个项目。 官方推荐使用LangChainHub&#xff0c;但是它在GitHub已经一年没有更新了&#x…

flutter多入口点entrypoint

native中引擎对象本身消耗内存(每个引擎对象约莫消耗42MB内存) 多引擎&#xff1a;native多引擎>启动>flutter多入口点entrypoint>多main函数>多子包元素集>多(子)程序 单引擎(复用)&#xff1a;native单引擎>复用启动>flutter多入口点entrypoint>多m…

高等数学基础篇之关于圆,椭圆,圆环的应用

文章目录 前言 1.圆 1.1标准方程 1.2偏心圆 1.3参数方程 2.椭圆 2.1标准方程 2.2参数方程 2.3极坐标 3.圆环 4.扇形 前言 这篇文章主要是应对二重积分出现的一些关于圆的积分域&#xff0c;让大家大概了解一下&#xff0c;不是很详细&#xff0c;因为二重积分对几何…

uniapp请求后端接口

新建文件夹utils const request (config) > {// 拼接完整的接口路径config.url http://mm.test.cn config.url;//这里拼接的是访问后端接口的地址&#xff0c;http://mm.test.cn/prod-api/testconsole.log(config.url)//判断是都携带参数if(!config.data){config.data …