Java调用Lua脚本(热载实现)
前言:
Lua作为解析执行的脚本语言, 往往是易变逻辑编写的首选语言, 尤其是在游戏领域. C/C++和Lua的结合, 往往了标配. 比如Redis, Nginx其对Lua的支持, 也是杠杠的. 当然Lua也可以作为规则引擎中的规则编写语言. 本文对Java调用Lua(Luaj)的实现机制, 做下简单的介绍.
Luaj简介:
Luaj是Java调用Lua的一种实现方式, 其是构建一个虚拟机解析执行Lua脚本来实现的, 这和Groovy的方式有所不同.
这是Luaj的官网, http://www.luaj.org/luaj/3.0/README.html.
它是针对5.2.x的lua版本的解析器, 其Luaj库的编写是通过JavaCC来实现的.
简单示例:
集合Luaj, 可以通过Maven进行如下配置:
<dependency><groupId>org.luaj</groupId><artifactId>luaj-jse</artifactId><version>3.0.1</version></dependency>
Luaj的一个简单的示例程序:
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;public class TestLuaJ {public static void main(String[] args) {String luaStr = "print 'hello,world!'";Globals globals = JsePlatform.standardGlobals();LuaValue chunk = globals.load(luaStr);chunk.call();}}
注: Globals继承LuaValue对象,LuaValue对象用来表示在Lua语言的基本数据类型,比如:Nil,Number,String,Table,userdata,Function等。尤其要注意LuaValue也表示了Lua语言中的函数。所以,对于Lua语言中的函数操作都是通过LuaValue来实现的.
其输出的结果:
hello,world!
原理初探:
根据官方的说法, Luaj在包装执行具体的Lua代码时, 有三种不同的模式.
1). 纯脚本解析执行(不选用任何Compiler)
2). To Lua字节码(LuaC, lua-to-lua-bytecode compiler)
3). To Java字节码(LuaJC, lua-to-java-bytecode compiler)
其中LuaC是默认的选用Compiler.
依据官方的介绍:
不使用LuaC的方法是, 则不调用如何行:
org.luaj.vm2.compiler.LuaC.install(globals);
而使用LuaJC的方法, 则是调用
org.luaj.vm2.jse.luajc.LuaJC.install(globals);
可惜, 笔者在自己测试过程中, 遇到了异常(org.luaj.vm2.LuaError: No compiler.), 好尴尬:
性能评估:
对Lua解析的代码进行简单的性能评估:
其对同样的逻辑代码:
int a = 0;for ( int i = 0; i < 10000; i++ ) {a = a + i;}
执行10000次, 具体对比耗时值.
整体的测试代码如下:
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;public class TestLuaJPerf {public static void main(String[] args) {int iterNum = 10000;// *) java 模式运行long beg = System.currentTimeMillis();for ( int j = 0; j < iterNum; j++ ) {int a = 0;for ( int i = 0; i < 10000; i++ ) {a = a + i;}}long end = System.currentTimeMillis();System.out.println(String.format("Java consume: %dms", end - beg));// *) Lua脚本解析执行String luaStr = "a = 0; for i = 0, 10000, 1 do a = a + i; end";Globals globals = JsePlatform.standardGlobals();LuaValue chunk = globals.load(luaStr);beg = System.currentTimeMillis();for ( int i = 0; i < iterNum; i++ ) {chunk.call();}end = System.currentTimeMillis();System.out.println(String.format("Lua consume: %dms", end - beg));}}
测试结果如下:
Java consume: 10ms Lua consume: 10249ms
几乎1000倍的差异, 这个性能对比, 差异有些大, Lua确实慢的不止半点(可能和Luaj的具体实现也有些关系), 因此从这方面来说, Java+Groovy的结合, 比Java+Lua的结合更有优势.
线程安全:
Luaj中的Globals对象不是线程安全的, 因此最佳实践是每个线程一个Globals对象.
事实上, 可以采用ThreadLocal的方式来存储该对象.
因为是对象, 而不是Class, 其和Groovy编译的Script类, 其实现思路是本质区别的.
总结:
个人对Luaj的认识还是有些肤浅, 没有深入地去研究, 所以可能这边的一些结论可能不准确. 同时Luaj对Lua脚本的支持, 到什么程度, 其实也是一个问号. 不管怎么样, 能对Luaj能有一个初步的认识, 也是好事.
Java调用Lua脚本(热载实现)相关推荐
- Java调用Lua(转)
Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些. 所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个 ...
- java调用Groovy脚本
一.使用 用 Groovy 的 GroovyClassLoader ,它会动态地加载一个脚本并执行它.GroovyClassLoader是一个Groovy定制的类装载器,负责解析加载Java类中用到的 ...
- java使用lua脚本操作 redis_在Redis中使用简单强大的Lua脚本
Redis分布式锁加锁 前段时间写Redis分布式锁,想着在小灰文章的基础上再总结一下,这样能有更深的印象,顺便把Lua脚本分享一下,如果项目中使用Redis比较多,那么Lua脚本一定是会用到的,因为 ...
- java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法
JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...
- Java调用python脚本
Java调用python脚本 最近也是刚开始学python,所以这里写了一个简单的小方法用Java来调用python脚本.后期再进行更新. 1.Java启动程序的方法 在Java中提供了两种方法来启动 ...
- Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本
Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本 首先参考http://wiki.chumby.com/index.php?title=Lua&print ...
- java 调用python脚本过程_通过Java调用Python脚本
在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势.最近在工作中遇到需要在Java程序中调用已经写好的Python程 ...
- 详解C调用lua脚本效率测试
详解C调用lua脚本效率测试 C调用lua脚本效率测试是本文要介绍的内容,以下代码以C语言为基准,测试了C调用Lua循环和循环调用Lua的效率.结论是不要频繁地穿越C/Lua边界. #include ...
- java 调用linux 脚本并获取返回值
大家好,我是烤鸭: 今天分享下java 调用 shell脚本 并获取返回值. 代码实践 String cmd = "df -h"; StringBuffer sb = new St ...
最新文章
- Objective C内存管理之理解autorelease------面试题
- 正则表达式中$1,$2 ===算是什么意思
- Android SharedPreferences 详解 源码解析
- Asp.Net Core 发布到IIS
- git两个账号切换_多个git账号之间的切换
- 如何在家访问公司的文件服务器,企业的共享文件,该怎么高效管理?
- 转:vSphere 7简介:混合云的功能和技术
- 【Statistics】均值
- RTC硬件时钟设置修改【转】
- 基因组组装---基因组大小评估(genome survey)
- Linux系统中三处profile的作用
- 2021中国AI产业10大趋势,一分钟看明白 | WAIC2021
- SI522A/SI523带低功耗自动寻卡功能的13.56MHz非接触式读写器芯片
- QT打印打印excel
- 卸载asterisk
- 学习日记day09 ps
- 怎样访问远程服务器文件夹,访问远程服务器的共享文件夹
- Cookie&Session
- Linux 多种方式实现文件共享
- oracle版本和驱动ojdbc、jdk版本对应关系