文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java代码中与Lua相互调用实现详解

2024-04-02 19:55

关注

一、方案

Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。

目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的小伙伴欢迎关注下。

目前最常见的方案:luaj,纯Java实现的Lua解析器,基于Lua 5.2

LuaJ的原理:用Java实现了一套Lua的编译器,本质上是把Lua文件中的Lua语言动态编译成了Java字节码,因此会收到诸多限制(比如第三方库的问题),而LuaJ本质上也只是运行在JVM上的Java字节码,和运行在C编译器环境下的Lua是有区别的

Maven pom

虽然源码已有3.0.2版本,但作者未上传maven,如有需要,可以自行导入jar包(源码中已打好3.0.2的jar包)

<dependency>
    <groupId>org.luaj</groupId>
    <artifactId>luaj-jse</artifactId>
    <version>3.0.1</version>
</dependency>

二、性能测试

以下我们以最基本的for循环并执行加法操作为例,分别在java外部for一万次,并在lua内部再for一万次

java原生代码

原生代码执行时间:1ms ~ 2ms

private static void runJava(int iterNum) {
    beg = System.currentTimeMillis();
    for (int j = 0; j &lt; iterNum; j++) {
        int a = 0;
        for (int i = 0; i &lt; 10000; i++) {
            a = a + i;
        }
    }
    end = System.currentTimeMillis();
}

lua脚本

function test()
    a = 0;
    for i = 0, 10000, 1 do
        a = a + i;
    end
end

1. ScriptEngine调用方式

调用方式:外部10000次调用,lua内部10000次循环a++ 总时间:8.9s左右 平均一次lua方法调用(1w次a++):0.89ms lua内部一次循环调用(1次a++):0.000089ms 修改lua内部循环1次 时间:10ms 平均一次lua方法调用:0.001ms

// ==================================================================================
// ScriptEngine方式
// ==================================================================================
Reader reader = new FileReader(luaStr);
LuaScriptEngine luaScriptEngine = (LuaScriptEngine) new LuaScriptEngineFactory().getScriptEngine();
// 使用luajc编译器,比默认luac编译器快3倍
LuajContext context = (LuajContext) luaScriptEngine.getContext();
LuaJC.install(context.globals);
CompiledScript compiledScript = luaScriptEngine.compile(reader);
Bindings bindings = new SimpleBindings();
compiledScript.eval(bindings);
LuaFunction luafunc = (LuaFunction) bindings.get("test");
beg = System.currentTimeMillis();
for (int i = 0; i &lt; iterNum; i++) {
    luafunc.call();
}
end = System.currentTimeMillis();
// ==================================================================================

2. Globals调用方式

调用方式:外部10000次调用,lua内部10000次循环a++ 时间:2.3s左右 平均一次lua方法调用:0.23ms lua内部一次循环调用:0.000023ms 修改lua内部循环1次 时间:4ms 平均一次lua方法调用:0.0004ms

// ==================================================================================
// Global方式
// ==================================================================================
Globals globals = JsePlatform.standardGlobals();
// 使用luajc编译器,比默认luac编译器快3倍
LuaJC.install(globals);
LuaValue doFile = globals.get("dofile");
doFile.call(LuaValue.valueOf(luaStr));
LuaValue luaValue = globals.get("test");
beg = System.currentTimeMillis();
for (int i = 0; i &lt; iterNum; i++) {
    luaValue.call();
}
end = System.currentTimeMillis();
 1w*1w调用总时间平均一次lua脚本时间lua内部一次循环时间
Java1ms-2ms--
ScriptEngine8.9s0.89ms0.000089ms
Globals2.3s0.23ms0.000023ms

3. lua调用java

把lua内的循环10000次,挪到java方法执行,java for(10000) -> lua -> java for(10000)

function test()
    luaTestJava:javaLoop()
end

Java提供loop方法

public static void javaLoop() {
    int a = 0;
    for (int i = 0; i < 10000; i++) {
        a = a + i;
    }
}

Global调用方式:5ms ScriptEngine调用方式:30ms

三、结论

作者的文档里说,某些情况下,luajc编译模式的效率和基于C的lua效率差不多源码中的示例

四、其他调用方式?

脱离java环境的lua编译器,lua单独运行进程,提供服务,java跨进程调用服务(没有尝试过,不知道跨进程调用掉率如何,也不知道lua进程资源占用情况) 这样lua可以使用luajit,也不受版本限制(luaJ是5.2)

以上就是Java代码中与Lua相互调用实现详解的详细内容,更多关于Java代码与Lua相互调用的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯