WEB开发网
开发学院软件开发Java Java 编程的动态性,第 8 部分: 用代码生成取代反... 阅读

Java 编程的动态性,第 8 部分: 用代码生成取代反射

 2010-03-18 00:00:00 来源:WEB开发网   
核心提示: 性能检查已经介绍了 Javassist 和 BCEL 版本的方法构造,现在可以试用它们以了解它们工作的情况,Java 编程的动态性,第 8 部分: 用代码生成取代反射(6),在运行时生成代码的根本理由是用一些更快的的东西取代反射,所以最好加入性能比较以了解在这方面的改进,这个参数是以命令行的形式

性能检查

已经介绍了 Javassist 和 BCEL 版本的方法构造,现在可以试用它们以了解它们工作的情况。在运行时生成代码的根本理由是用一些更快的的东西取代反射,所以最好加入性能比较以了解在这方面的改进。为了更加有趣,我还将比较用两种框架构造 glue 类所用的时间。

清单 6 显示用于检查性能的测试代码的主要部分。 runReflection() 方法运行测试的反射部分, runAccess() 运行直接访问部分, run() 控制整个进程(包括打印时间结果)。 runReflection() 和 runAccess() 都取要执行的次数作为参数,这个参数是以命令行的形式传递的(使用的代码没有在清单中显示,但是包括在下载中)。 DirectLoader 类(在清单 6 的结尾)只提供了装载生成的类的一种容易的方式。

清单 6. 性能测试代码

/** Run timed loop using reflection for access to value. */ 
private int runReflection(int num, Method gmeth, Method smeth, 
  Object obj) { 
  int value = 0; 
  try { 
    Object[] gargs = new Object[0]; 
    Object[] sargs = new Object[1]; 
    for (int i = 0; i < num; i++) { 
       
      // messy usage of Integer values required in loop 
      Object result = gmeth.invoke(obj, gargs); 
      value = ((Integer)result).intValue() + 1; 
      sargs[0] = new Integer(value); 
      smeth.invoke(obj, sargs); 
       
    } 
  } catch (Exception ex) { 
    ex.printStackTrace(System.err); 
    System.exit(1); 
  } 
  return value; 
} 
/** Run timed loop using generated class for access to value. */ 
private int runAccess(int num, IAccess access, Object obj) { 
  access.setTarget(obj); 
  int value = 0; 
  for (int i = 0; i < num; i++) { 
    value = access.getValue() + 1; 
    access.setValue(value); 
  } 
  return value; 
} 
public void run(String name, int count) throws Exception { 
   
  // get instance and access methods 
  HolderBean bean = new HolderBean(); 
  String pname = name; 
  char lead = pname.charAt(0); 
  pname = Character.toUpperCase(lead) + pname.substring(1); 
  Method gmeth = null; 
  Method smeth = null; 
  try { 
    gmeth = HolderBean.class.getDeclaredMethod("get" + pname, 
      new Class[0]); 
    smeth = HolderBean.class.getDeclaredMethod("set" + pname, 
      new Class[] { int.class }); 
  } catch (Exception ex) { 
    System.err.println("No methods found for property " + pname); 
    ex.printStackTrace(System.err); 
    return; 
  } 
   
  // create the access class as a byte array 
  long base = System.currentTimeMillis(); 
  String cname = "IAccess$impl_HolderBean_" + gmeth.getName() + 
    "_" + smeth.getName(); 
  byte[] bytes = createAccess(HolderBean.class, gmeth, smeth, cname); 
   
  // load and construct an instance of the class 
  Class clas = s_classLoader.load(cname, bytes); 
  IAccess access = null; 
  try { 
    access = (IAccess)clas.newInstance(); 
  } catch (IllegalAccessException ex) { 
    ex.printStackTrace(System.err); 
    System.exit(1); 
  } catch (InstantiationException ex) { 
    ex.printStackTrace(System.err); 
    System.exit(1); 
  } 
  System.out.println("Generate and load time of " + 
    (System.currentTimeMillis()-base) + " ms."); 
   
  // run the timing comparison 
  long start = System.currentTimeMillis(); 
  int result = runReflection(count, gmeth, smeth, bean); 
  long time = System.currentTimeMillis() - start; 
  System.out.println("Reflection took " + time + 
    " ms. with result " + result + " (" + bean.getValue1() + 
    ", " + bean.getValue2() + ")"); 
  bean.setValue1(0); 
  bean.setValue2(0); 
  start = System.currentTimeMillis(); 
  result = runAccess(count, access, bean); 
  time = System.currentTimeMillis() - start; 
  System.out.println("Generated took " + time + 
    " ms. with result " + result + " (" + bean.getValue1() + 
    ", " + bean.getValue2() + ")"); 
} 
/** Simple-minded loader for constructed classes. */ 
protected static class DirectLoader extends SecureClassLoader 
{ 
  protected DirectLoader() { 
    super(TimeCalls.class.getClassLoader()); 
  } 
   
  protected Class load(String name, byte[] data) { 
    return super.defineClass(name, data, 0, data.length); 
  } 
} 

上一页  1 2 3 4 5 6 7 8  下一页

Tags:Java 编程 动态性

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接