博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java调用Lua脚本(热载实现)
阅读量:7213 次
发布时间:2019-06-29

本文共 3034 字,大约阅读时间需要 10 分钟。

 

前言:

  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进行如下配置:

org.luaj
luaj-jse
3.0.1

  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: 10msLua consume: 10249ms

  几乎1000倍的差异, 这个性能对比, 差异有些大, Lua确实慢的不止半点(可能和Luaj的具体实现也有些关系), 因此从这方面来说, Java+Groovy的结合, 比Java+Lua的结合更有优势.

线程安全:
  Luaj中的Globals对象不是线程安全的, 因此最佳实践是每个线程一个Globals对象.
  事实上, 可以采用ThreadLocal的方式来存储该对象.
  因为是对象, 而不是Class, 其和Groovy编译的Script类, 其实现思路是本质区别的.

 

总结:

  个人对Luaj的认识还是有些肤浅, 没有深入地去研究, 所以可能这边的一些结论可能不准确. 同时Luaj对Lua脚本的支持, 到什么程度, 其实也是一个问号. 不管怎么样, 能对Luaj能有一个初步的认识, 也是好事.

 

转载地址:http://kmrum.baihongyu.com/

你可能感兴趣的文章
Alibaba Cloud Launches Dual-mode SSD to Optimize Hyper-scale Infrastructure Performance
查看>>
数字签名和数字证书详解
查看>>
用来代替SQUID的软件VARNISH
查看>>
每天学一点Scala之 伴生类和伴生对象
查看>>
http反向代理调度算法追朔
查看>>
做门户网站 个人站长的新好出路
查看>>
sql中exists,not exists的用法
查看>>
CentOS6.5更改ssh端口问题
查看>>
11g默认审计选项
查看>>
Where Did That New Exchange 2010 Mailbox Go?
查看>>
CentOS 7 yum安装Zabbix
查看>>
Bash编程入门
查看>>
神器:REST测试工具[wiztools.org restclient]客户端Jar依赖Java安装环境
查看>>
生成keystore是报错拒绝访问(已测试)
查看>>
从一道题浅说 JavaScript 的事件循环
查看>>
每天进步一点点——Linux文件锁编程flock
查看>>
sqlserver锁机制详解(sqlserver查看锁)
查看>>
[公告]欢迎您加入WF技术研究团队
查看>>
5.10. Web Tools
查看>>
将Eclipse代码导入到Android Studio的两种方式
查看>>