lisp java_LSP开发——ABCL,LISP、JAVA互调

作者:宋云

使用ABCL的效率问题

最初使用ABCL在LISP中调用JAVA类是总是找不到类,查阅ABCL的样例README总算找到一个靠谱的方法:

javac -cp

abcl.jar Main.java

java -cp abcl.jar;. Main

需要注意java文件的package,一定要对应,否则同样找不到.class。按照ABCL的样例做如下实验,下面是Main.lisp中定义的函数:

(defun void-function

(param)

(let* ((class (jclass

"Main"))

(intclass

(jclass "int"))

(method (jmethod class

"addTwoNumbers" intclass intclass))

(result (jcall method

param 2 5)))

(format

t "in void-function, result of calling addTwoNumbers(2, 5): ~a~%"

result)))

该函数执行类Main的方法addTwoNumbers,下面是Main.java:

import org.armedbear.lisp.Fixnum;

import org.armedbear.lisp.Function;

import org.armedbear.lisp.Interpreter;

import org.armedbear.lisp.JavaObject;

import org.armedbear.lisp.LispObject;

import org.armedbear.lisp.Packages;

import org.armedbear.lisp.Symbol;

public class Main{

public

static void main(String[] argv){

try{

long

btime = System.currentTimeMillis();

Main

thisObject= new Main();

System.out.println("Main:"+(System.currentTimeMillis()-btime));

Interpreter

interpreter= Interpreter.createInstance();

System.out.println("Interpreter:"+(System.currentTimeMillis()-btime));

interpreter.eval_r("(load

\"Main.lisp\")");

System.out.println("Load:"+(System.currentTimeMillis()-btime));

// the function is not in a separate package, thus

the43

//

correct package is CL-USER. Symbol names are44

//

upper case. Package needs the prefix, because

java45

//

also has a class named Package.46

org.armedbear.lisp.Package

defaultPackage=

Packages.findPackage("CL-USER");

System.out.println("DefPackage:"+(System.currentTimeMillis()-btime));

Symbol

voidsym= defaultPackage.findAccessibleSymbol("VOID-FUNCTION");

System.out.println("Find

Symbol:"+(System.currentTimeMillis()-btime));

Function

voidFunction= (Function)

voidsym.getSymbolFunction();

System.out.println("voidFunction:"+(System.currentTimeMillis()-btime));

LispObject

lo = voidFunction.execute(new

JavaObject(thisObject));

System.out.println("execute:"+(System.currentTimeMillis()-btime));

System.out.println(lo.toString());

}catch

(Throwable t){

System.out.println("exception!");

t.printStackTrace();

}

}

public

int addTwoNumbers(int a, int b)

{

return a+ b;

}

}

该类执行Main.lisp,在Main.lisp中调用自身的addTwoNumbers,同时输出每一步距离程序刚开始运行时所消耗的时间(单位毫秒),运行结果:

Main:0

Interpreter:12313

Load:12360

DefPackage:12360

Find

Symbol:12360

voidFunction:12360

in void-function, result

of calling addTwoNumbers(2, 5): 7

execute:31641

COMMON-LISP:NIL

很明显,创建Interpreter很耗时间12313毫秒,而反调用java中的函数更好时间(31641-12360=19281毫秒),耗时非常吓人,恐怕用来做WebServer很值得考虑。

但是考虑到这个函数的执行过程很复杂,调用了lisp又返回来调用Java。下面更改一下只调用纯lisp函数:

(defun add (a b

c)

(+

a b c))

Symbol

voidsym= defaultPackage.findAccessibleSymbol("ADD");

LispObject lo =

voidFunction.execute(Fixnum.getInstance(1),

Fixnum.getInstance(2),

Fixnum.getInstance(3));

计算结果如下:

Main:0

Interpreter:13141

Load:13172

DefPackage:13172

Find

Symbol:13172

voidFunction:13172

execute:13172

org.armedbear.lisp.Fixnum@6

这表明纯粹的调用LISP函数并不消耗多少时间,基本就等于LISP函数的执行时间。因此可以考虑在JAVA中调用纯LISP函数。

ABCL资料如此只少,真心需要多花点时间琢磨了!

JAVA中调用LISP函数

下面介绍在JAVA中调用LISP的过程。首先要获取一个解析器实例:

Interpreter

interpreter= Interpreter.createInstance();

通过解析器载入lisp文件:

interpreter.eval_r("(load

\"Main.lisp\")");

获取包:

org.armedbear.lisp.Package

defaultPackage=

Packages.findPackage("CL-USER");

寻找函数标示:

Symbol

voidsym=

defaultPackage.findAccessibleSymbol("VOID-FUNCTION");

获取函数实例:

Function

voidFunction= (Function)

voidsym.getSymbolFunction();

执行函数:

LispObject lo =

voidFunction.execute(

new

JavaObject(thisObject));

至于如何设置函数输入参数的类型还有待研究。

cce544e7261bf3a4535656c82b969b03.png

转发至微博

cce544e7261bf3a4535656c82b969b03.png

转发至微博

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值