.NET下几种动态生成代码方式比较
2004-09-10 11:59
579 查看
场景:
平时在日常工作中往往会遇到这样的情况:一般的解决方案性能不是最好的,但性能最好的解决方案往往又不一定容易理解。如何兼顾这两者呢?这里有一个Microsoft网站上的例子,它用了几种动态代码生成的方法去实现同一个问题,可以对它们的性能做一个简单的比较,以后到底用那种方法心中就有数了。
要解决的问题:
计算一个多项式的值:
Y = A0 + A1 * X + A2 * X2 + … + An * Xn
比较指标:
1. 参数只有一个的情况: A0=5.5
2. 参数只有7个的情况: A0=5.5 A1=7.0 A2=15 A3=30 A4=500 A5=100 A6=1
3. 参数有30个的情况:A0=0 A1=1 ... A29=29
4. 参数有50个的情况:A0=0 A1=1 ... A49=49
5. 参数有100个的情况:A0=0 A1=1 ... A99=99
实现方式:
最普通的用循环的实现方式:(不涉及动态编程的内容,参考作用)
对参数进行循环。
public override double Evaluate(double value)
显然这样的方式循环是很多的,这里对参数循环,外面还要对指数幂循环。为了减少循环的次数,考虑将上面Evaluate的方法用动态代码的方式实现。
// polynomial evaluator
// Evaluating y = 5.5 + 7 X^1 + 7 X^2 + 7 X^3 + 7 X^4 + 7 X^5 + 7 X^6
class Poly_1
// polynomial evaluator
// Evaluating y = 5.5 + 7 X^1 + 15 X^2 + 30 X^3 + 500 X^4 + 100 X^5 + 1 X^6
class Poly_1001: PolyInterface.IPolynomial
// Polynomial evaluator
// Evaluating Y = 5.5 + 7 X^1 + 15 X^2 + 30 X^3 + 500 X^4 + 100 X^5 + 1 X^6
public class Poly_1001 : PolyInterface.IPolynomial {
public double Evaluate(System.Double x) {
return (5.5
+ (x
* (7
+ (x
* (15
+ (x
* (30
+ (x
* (500
+ (x
* (100
+ (x
* (1 + 0)))))))))))));
}
}
4.<<PolyEmit.cs>>
这里直接用元编程技术,跳过文本编译生成的过程,直接生成动态编译结果然后调用。
a.建立动态程序集;
b.元编程技术实现动态类和方法;
c.通过动态类的接口调用结果;
结果比较: (数据是在机子上某次运行的结果)
动态代码花费的时间(主要花费在代码编译上)
每秒可以运行多少个表达式(性能比较)
由此可见:
后面三种动态方式的性能差不多,虽然元编程不花费时间在编译上,但其技术难度相对也高些。
相关例子下载
平时在日常工作中往往会遇到这样的情况:一般的解决方案性能不是最好的,但性能最好的解决方案往往又不一定容易理解。如何兼顾这两者呢?这里有一个Microsoft网站上的例子,它用了几种动态代码生成的方法去实现同一个问题,可以对它们的性能做一个简单的比较,以后到底用那种方法心中就有数了。
要解决的问题:
计算一个多项式的值:
Y = A0 + A1 * X + A2 * X2 + … + An * Xn
比较指标:
1. 参数只有一个的情况: A0=5.5
2. 参数只有7个的情况: A0=5.5 A1=7.0 A2=15 A3=30 A4=500 A5=100 A6=1
3. 参数有30个的情况:A0=0 A1=1 ... A29=29
4. 参数有50个的情况:A0=0 A1=1 ... A49=49
5. 参数有100个的情况:A0=0 A1=1 ... A99=99
实现方式:
最普通的用循环的实现方式:(不涉及动态编程的内容,参考作用)
对参数进行循环。
public override double Evaluate(double value)
显然这样的方式循环是很多的,这里对参数循环,外面还要对指数幂循环。为了减少循环的次数,考虑将上面Evaluate的方法用动态代码的方式实现。
// polynomial evaluator
// Evaluating y = 5.5 + 7 X^1 + 7 X^2 + 7 X^3 + 7 X^4 + 7 X^5 + 7 X^6
class Poly_1
// polynomial evaluator
// Evaluating y = 5.5 + 7 X^1 + 15 X^2 + 30 X^3 + 500 X^4 + 100 X^5 + 1 X^6
class Poly_1001: PolyInterface.IPolynomial
// Polynomial evaluator
// Evaluating Y = 5.5 + 7 X^1 + 15 X^2 + 30 X^3 + 500 X^4 + 100 X^5 + 1 X^6
public class Poly_1001 : PolyInterface.IPolynomial {
public double Evaluate(System.Double x) {
return (5.5
+ (x
* (7
+ (x
* (15
+ (x
* (30
+ (x
* (500
+ (x
* (100
+ (x
* (1 + 0)))))))))))));
}
}
4.<<PolyEmit.cs>>
这里直接用元编程技术,跳过文本编译生成的过程,直接生成动态编译结果然后调用。
a.建立动态程序集;
b.元编程技术实现动态类和方法;
c.通过动态类的接口调用结果;
结果比较: (数据是在机子上某次运行的结果)
动态代码花费的时间(主要花费在代码编译上)
花费时间(s) | 1个参数 | 7个参数 | 30个参数 | 50个参数 | 100个参数 |
一般代码方式(PolySimple.cs) | 0 | 0 | 0 | 0 | 0 |
动态代码方式一(PolyCodeSlow.cs) | 0.49 | 0.37 | 0.34 | 0.34 | 0.36 |
动态代码方式二(PolyCode.cs) | 0.47 | 0.4 | 0.36 | 0.37 | 0.43 |
动态代码方式三(PolyCodeDom.cs) | 0.51 | 0.38 | 0.43 | 0.39 | 0.38 |
动态代码方式四(PolyEmit.cs) | 0.01 | 0 | 0 | 0 | 0 |
1个参数 | 7个参数 | 30个参数 | 50个参数 | 100个参数 | |
一般代码方式(PolySimple.cs) | 24844149 | 10976159 | 3606267 | 2107176 | 1050327 |
动态代码方式一(PolyCodeSlow.cs) | 59905 | 59525 | 58981 | 57860 | 56057 |
动态代码方式二(PolyCode.cs) | 80258857 | 11703214 | 2973909 | 1930444 | 980942 |
动态代码方式三(PolyCodeDom.cs) | 113636349 | 11001798 | 2960087 | 1917754 | 769594 |
动态代码方式四(PolyEmit.cs) | 113636349 | 11916722 | 2935906 | 1925118 | 859074 |
后面三种动态方式的性能差不多,虽然元编程不花费时间在编译上,但其技术难度相对也高些。
相关例子下载
相关文章推荐
- Unity中资源动态加载的几种方式比较
- java中操作xml几种方式的比较和代码示例(DOM,SAX,JDOM,DOM4J)
- mybatis代码生成的几种方式
- 写一个静态HTML页面,直接写HTML代码和用JS动态生成代码,哪种方式要好
- mybatis代码生成的几种方式
- mybatis代码生成的几种方式
- 参考.net类库代码的几种方式
- 【Visual Basic】纯代码不拖控件,利用动态生成控件的方式完成一个简单的四则运算计算器
- mybatis代码生成工具mybatis-generator调用有好几种方式
- 一起谈.NET技术,从数据到代码—基于T4的代码生成方式
- .net导出Excel几种方式比较
- 使用ABAP和JavaScript代码生成PDF文件的几种方式
- 代码笔记:wordpress后台添加菜单的几种方式比较
- Unity中资源动态加载的几种方式比较
- 使用ABAP和JavaScript代码生成PDF文件的几种方式
- 使用.net 中的动态方法编程备忘录1(如何查看生成的动态方法的代码)
- hibernate中主键的几种生成方式比较
- MyBatis Generator生成代码的几种方式
- .NET测试代码效率(时间比较方式)
- java中操作xml几种方式的比较和代码示例(DOM,SAX,JDOM,DOM4J)