前言:
  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脚本(热载实现)的更多相关文章

  1. Java调用Lua脚本(LuaJava使用、安装及Linux安装编译)

    依赖包(附件有下载): 包名 类型 操作系统 luajava-1.1.jar jar ALL libluajava-1.1.so .so linux luajava-1.1.dll .dll wind ...

  2. Java调用Lua(转)

    Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些.所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个模 ...

  3. Redis进阶实践之八Lua的Cjson在Linux下安装、使用和用C#调用Lua脚本

    一.引言         学习Redis也有一段时间了,感触还是颇多的,但是自己很清楚,路还很长,还要继续.上一篇文章简要的介绍了如何在Linux环境下安装Lua,并介绍了在Linux环境下如何编写L ...

  4. lua调用java java调用lua[转载]

    转载:http://dualface.github.io/blog/2013/01/01/call-java-from-lua/LuaJavaBridge - Lua 与 Java 互操作的简单解决方 ...

  5. 用C#调用Lua脚本

    用C#调用Lua脚本 一.引言 学习Redis也有一段时间了,感触还是颇多的,但是自己很清楚,路还很长,还要继续.上一篇文章简要的介绍了如何在Linux环境下安装Lua,并介绍了在Linux环境下如何 ...

  6. java调用python脚本并向python脚本传递参数

    1.安装Eclipse 先安装jdk,再安装Eclipse,成功后开始建立py_java项目,在这个项目的存储目录SRC下建立test包,在test包中New-Class,新建MyDemo类,建好完成 ...

  7. Java 调用 shell 脚本详解

    这一年的项目中,有大量的场景需要Java 进程调用 Linux的bash shell 脚本实现相关功能. 从之前的项目中拷贝的相关模块和网上的例子来看,有个别的“陷阱”造成调用shell 脚本在某些特 ...

  8. (转)java调用python脚本

    这篇博客旨在吐血分享今天遇到的java调用python脚本遇到的坑,折腾了3个多小时终于可以跑通了,代码超级短,但网上的好多资料都是抄来抄去的,很少有能够直接跑通的,尤其是针对你的python文件中用 ...

  9. 通过Java调用Python脚本

    在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势.最近在工作中遇到需要在Java程序中调用已经写好的Python程 ...

随机推荐

  1. 牛客多校第三场 A—pacm team (4维背包加路径压缩)

    链接:https://www.nowcoder.com/acm/contest/141/A 来源:牛客网 Eddy was a contestant participating , Eddy fail ...

  2. iOS runtime实用篇--和常见崩溃say good-bye!

    程序崩溃经历 其实在很早之前就想写这篇文章了,一直拖到现在. 程序崩溃经历1 我们公司做的是股票软件,但集成的是第三方的静态库(我们公司和第三方公司合作,他们提供股票的服务,我们付钱).平时开发测试的 ...

  3. Binary Analysis Tool安装使用教程

    Binary Analysis Tool(BAT)是一个用于检测二进制文件使用到的开源组件,协助及早发现程序发布后可能会面临的开源协议解执的开源免费检测工具. 一.安装BAT和bat-extratoo ...

  4. QAbstractItemView区分单双击

    系统不可能知道你这一次单击鼠标是为了双击指令,所以在你第一次按下鼠标时,系统会发出一个WM_XBUTTONDOWN(也就是clicked), 当你第二次单击鼠标时,系统先发送WM_XBUTTONDOW ...

  5. SpringBoot鸡汤(注解集合二)

    1.@NotNull :属性值不为空 2.@Profiles @Configuration @Profile("production") public class Producti ...

  6. 梯度下降法的三种形式BGD、SGD以及MBGD

    https://www.cnblogs.com/maybe2030/p/5089753.html 阅读目录 1. 批量梯度下降法BGD 2. 随机梯度下降法SGD 3. 小批量梯度下降法MBGD 4. ...

  7. laravel模型中设计使用单选按钮的方法:

    模型中写入: const SEX_UN = 10;//未知: const SEX_BOY = 20;//男 const SEX_GRIL = 30;//女 public function sex($i ...

  8. asp.net 发送电子邮件本地测试正常,但服务器上异常的解决办法

    如题,这个问题曾经非常苦恼,代码肯定是没有问题的.在网上也查找了不少资料,按照他们的步骤做了,还是无效. 最后问题解决了,原来:我租用腾讯云服务器,腾讯为了防止垃圾邮件,禁止了邮件发送的25号端口,原 ...

  9. bzoj1239

    题解: 首先计算出两两之间的距离 然后二分答案 然后贪心判断是否可以放置少于等于k个 代码: #include<bits/stdc++.h> using namespace std; ; ...

  10. 跑caffe过程中的备忘

    1*1卷积比如一张500*500且厚度depth为100的图片在20个filter上做1*1卷积,那么结果大小为500*500*20 只有池化改变图片的大小 一个大的全连接层可以理解为一个神经网络,这 ...