jdk 1.6 新特性,集成Groovy, 性能很差

性能都是相对的,如果调用量不是很大的话,可以忽略,毕竟使用为主。groovy支持的语法还是很多的,灰常推荐,我这只是小实验罢了

代码执行如下:

/**
* @param args
* @throws ScriptException
*/
public static void main(String[] args) throws ScriptException {
// TODO Auto-generated method stub
ScriptEngineManager sem = new ScriptEngineManager();
//sem.registerEngineName("frame", new FrameScriptEngineFactory());
ScriptEngine engine = sem.getEngineByName("groovy");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("tag", new TagImpl());
bindings.put("bcontext", new BContext(9));
bindings.put("account", 9);
long s = System.currentTimeMillis();
for(int i=0;i<10000;i++){
Object result = engine.eval("tag.hasTag(account)");
Object result1 = engine.eval("tag.hasTag(account)");
Object result2 = engine.eval("tag.isManager(bcontext)");
}
System.out.println(System.currentTimeMillis()-s);
//No cache 234 203 187
//cache 125 141 141 125
//groovy 2375 1796 1719
}



这是我测试的结果,使用反射与使用groovy的差距。
其实反射没有大家想像的这么慢, 反射缓存Method后,性能可以提升差不多2倍.

这个测试我实现了自己的ScriptEngineFactory,并使用jdk的反射机制与Groovy进行对比。

package org.miniframe.modules.script;

import javax.script.ScriptEngine;

/**
* this is a factory to product ScriptEngine.
*/
public class FrameScriptEngineFactory extends AbstractScriptEngineFactory {

@Override
public String getEngineName() {
return "frame";
}

@Override
public String getEngineVersion() {
return "1.0";
}

@Override
public ScriptEngine getScriptEngine() {
FrameScriptEngine framese = new FrameScriptEngine(this);
return framese;
}

}




package org.miniframe.modules.script;

import java.io.Reader;

import javax.script.AbstractScriptEngine;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;

public class FrameScriptEngine extends AbstractScriptEngine{

private FrameScriptEngineFactory framesef;

public FrameScriptEngine(FrameScriptEngineFactory framesef){
super();
this.framesef=framesef;
}

@Override
public ScriptEngineFactory getFactory() {
return framesef;
}


/**
*
* 1. first compile script to compileScript
* 2. execute compoleScript to get result.
*/
@Override
public Object eval(String script, ScriptContext context)
throws ScriptException {
FrameCompilable compiled = new FrameCompilable();
FrameCompiledScript compiledScript = (FrameCompiledScript) compiled.compile(script);
return compiledScript.eval(context);
}


@Override
public Object eval(Reader reader, ScriptContext context)
throws ScriptException {
// TODO Auto-generated method stub
return null;
}


@Override
public Bindings createBindings() {
// TODO Auto-generated method stub
return null;
}

}




package org.miniframe.modules.script;

import java.io.Reader;
import java.util.HashMap;
import java.util.Map;

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptException;

public class FrameCompilable implements Compilable {

private Map<String,CompiledScript> compiledCache = new HashMap<String,CompiledScript>();

@Override
public CompiledScript compile(String script) throws ScriptException {
CompiledScript compiledScript = compiledCache.get(script);
if(compiledScript!=null){
return compiledScript;
}else{
FrameCompiledScript frameScript = new FrameCompiledScript();
frameScript.compile(script);
compiledCache.put(script, frameScript);
compiledScript = frameScript;
}
return compiledScript;
}

@Override
public CompiledScript compile(Reader script) throws ScriptException {
// TODO Auto-generated method stub
return null;
}

}




package org.miniframe.modules.script;

import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class FrameCompiledScript extends CompiledScript {

private String script;
private String target;
private String method;
private String[] args;

public String getTarget() {
return target;
}

public void setTarget(String target) {
this.target = target;
}

public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

public String[] getArgs() {
return args;
}

public void setArgs(String[] args) {
this.args = args;
}

public void compile(String script){
this.script=script;
String[] fs = script.split("\\.");
if(fs.length==2){
String target = fs[0];
String[] ss = fs[1].split("\\(");
String method = ss[0];
String[] args = ss[1].substring(0, ss[1].length()-1).split(",");
setTarget(target);
setMethod(method);
setArgs(args);
}
}

@Override
public Object eval(ScriptContext context) throws ScriptException {
FrameInvocable invocable = new FrameInvocable(script);
Bindings binding = context.getBindings(ScriptContext.ENGINE_SCOPE);
Object[] objargs = new Object[args.length];
for(int i=0;i<args.length;i++){
Object objarg = binding.get(args[i]);
objargs[i]=objarg;
}
Object obj = null;
try {
obj = invocable.invokeMethod(binding.get(target), method, objargs);
} catch (NoSuchMethodException e) {
}
return obj;
}

@Override
public ScriptEngine getEngine() {
// TODO Auto-generated method stub
return null;
}

}




package org.miniframe.modules.script;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptException;

public class FrameInvocable implements Invocable {

private static Map<String, Method> methodCache = new HashMap<String, Method>();

private boolean flag = true;

private String script;

public FrameInvocable(String script) {
this.script = script;
}

@SuppressWarnings("rawtypes")
@Override
public Object invokeMethod(Object thiz, String name, Object... args)
throws ScriptException, NoSuchMethodException {
Method method = methodCache.get(script);
Object re = null;
if (method != null) {
re = invoke(thiz, method, args);
} else {
Class[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
parameterTypes[i] = args[i].getClass();
}
method = getMethod(thiz, name, parameterTypes);
if(flag){
methodCache.put(script, method);
}
re = invoke(thiz, method, args);
}

return re;
}

/**
* search method from me and parents
*
* @param target
* @param methodName
* @param args
* @return
*/
public static Method getMethod(Object target, String methodName,
Class<?>... args) {
Method method = null;
try {
for (Class<?> searchType = target.getClass(); searchType != Object.class; searchType = searchType
.getSuperclass()) {
method = searchType.getDeclaredMethod(methodName, args);
if (method != null) {
return method;
}
}
} catch (SecurityException e) {
throw e;
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("invalid:no method ["
+ methodName + "] on target [" + target + "]", e);
}
return method;

}

/**
* invoke method
*
* @param target
* @param method
* @param args
* @return
* @throws Throwable
*/
public static Object invoke(Object target, Method method, Object[] args) {
try {
if (!Modifier.isPublic(method.getModifiers())
|| !Modifier.isPublic(method.getDeclaringClass()
.getModifiers())) {
method.setAccessible(true);
}
return method.invoke(target, args);
} catch (InvocationTargetException ex) {
throw new IllegalArgumentException(ex);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(
"invalid: tried calling method [" + method
+ "] on target [" + target + "]", ex);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException("Could not access method ["
+ method + "]", ex);
}
}

@Override
public Object invokeFunction(String name, Object... args)
throws ScriptException, NoSuchMethodException {
// TODO Auto-generated method stub
return null;
}

@Override
public <T> T getInterface(Class<T> clasz) {
// TODO Auto-generated method stub
return null;
}

@Override
public <T> T getInterface(Object thiz, Class<T> clasz) {
// TODO Auto-generated method stub
return null;
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值