多线程java应用程序中的javascript评估

时间:2014-02-06 12:22:30

标签: java-ee rhino

我们使用Rhino引擎来评估我们javaEE应用程序中的javascript。(我们使用javascript作为参数化。在DTO -s之间传递数据和条件参数化等)。 我们做了一些性能测试,结果很奇怪。

javascript引擎非常慢。并且持续时间呈指数增长。 我想将整个引擎改为Nashron,但在此之前我试着改进我们现在拥有的东西。

关于我们使用它的方式的一些代码片段(可能问题出在这里(?)) 每次我尝试评估表达式时,我都会以这种方式创建一个JavaScriptEval对象:

public void init() {

    Context cc = Context.getCurrentContext();
    if ( cc == null) {
        cc = Context.enter();
    }
    this.ctx = cc;
    this.scope =this.ctx.initStandardObjects(null);
    this.wrapFactory = new WrapFactory();
}

之后我们将对象 - 例如DTO -s-添加到范围

private void putObject(String id, Object obj) {

    Context ctx = setupContext();
    if (obj != null) {
        Scriptable paramWrapper = this.wrapFactory.wrapAsJavaObject(/*this.ctx*/ ctx, this.scope, obj, obj.getClass());
        this.scope.put(id, this.scope, paramWrapper);
    } 
}

之后我们用这种方式评估我们的表达式:

public Object eval(Object scriptId, String source){
    Object ret;
    ret = ctx.evaluateString(this.scope,source, scriptId.toString(), 1, null);  
    return ret;
}

我尝试过使用某种缓存方式。我使用了compileString方法然后将它放在缓存中。但是这样的内存使用量非常高。

之后我尝试限制我放入缓存的javascript源的长度。但问题是同时增加并发使用的性能是可怕的。

有什么想法吗? 欢迎提出所有建议

1 个答案:

答案 0 :(得分:0)

我认为没有好的答案:)

但我解决了这个问题: 我预先编译了表达式,如果它是一个简单的init(类似于dto.setA(1)),只需在java代码中执行它。

另一种方法是将分离的缓存用于分离的进程,然后将其删除。

这是解决此问题的一种非常明确的方法,但我适合我:)