再比较动态调用代码

原创 2004年09月14日 12:50:00

       上次在MSDN网站看到一个比较动态调用代码的文章,用到的例子似乎比较复杂,为计算一个复杂多项式子而将其中部分割开,动态形成代码段来被循环调用。详细看.NET下几种动态生成代码方式比较。今天看到微软C#团队的Eric Gunnerson写的另外一篇关于动态调用代码性能的比较文章,为了说明结果和计算的准确性,减少由于函数复杂而受编译优化的影响,他使用了一个极为简单的例子:
输入一个参数,然后返回这个参数加一,这么简单的函数,优化和没有优化的代码应该不会有差别的了。

None.gif    public class Processor
ExpandedBlockStart.gif    
{
InBlock.gif        
public int Process(int value)
ExpandedSubBlockStart.gif        
{
InBlock.gif            
return value + 1;
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

None.gif
None.gif


而对比方面,除了上次那几种外,还加了代理方式调用来进行比较。
1. 直接调用

None.gifint value = processor.Process(i);

2. 用反射机制,Type.InvokeMember()调用。

None.gif    Type t = typeof(Processor);
None.gif    
int value = 
None.gif        (
int) t.InvokeMember(
None.gif                  
"Process"
None.gif         BindingFlags.Instance 
| BindingFlags.Public | 
None.gif                  BindingFlags.InvokeMethod, 
ExpandedBlockStart.gif                  
null, processor, new object[] {i});
None.gif
None.gif

3. 通过一个接口

None.gif    public interface IProcessor
ExpandedBlockStart.gif   
{
InBlock.gif        
int Process(int value);
ExpandedBlockEnd.gif    }

None.gif
None.gif

4. 通过一个委托Delegate

None.gif    public delegate int ProcessCaller(int value);
None.gif    ProcessCaller processCaller 
= new ProcessCaller(processor.Process);
None.gif    
int value = processCaller(i); 
None.gif
None.gif

5. 也通过反射机制建立委托再动态调用

None.gif    Type delegateType = CreateCustomDelegate(methodInfo);
None.gif    Delegate p 
= Delegate.CreateDelegate(delegateType, 
None.gif                                         process, 
"Process");
ExpandedBlockStart.gif    
int value = (int) p.DynamicInvoke(new object[] {i});
None.gif
None.gif

6. 元编程方式

对于2和5由于使用反射机制,不可避免需要建立中间的临时对象去传递参数,将参数和返回值装箱等操作,因此花费了大量的机器时间。

下面是运行的某次结果(循环100000次):
dynaCall1.JPG



结论:
1.直接调用速度最快是肯定的。
2.接口调用比元编程速度快,而元编程又比委托方式快,但微软相信Whidbey会极大优化委托调用方式,从而使它接近接口调用的水平。
3.直接用Type的反射机制是速度最慢的,比用反射机制建立委托来动态调用还慢。
4.直接使用委托不够灵活,有时候需要用反射机制建立委托来调用,但会减低性能,希望Whidbey优化了委托的性能后这种情况可以改善,灵活是需要牺牲性能的。

相关代码

CXF客户端动态调用

问题一: 使用CXF实现WebService,并在客户端实现动态调用编写服务器注意事项 注意 :不要指定 @SOAPBinding(style=Style.RPC, use=Use.LITERA...
  • cuiyaoqiang
  • cuiyaoqiang
  • 2016年06月03日 11:49
  • 835

非常不错的C#动态调用DLL代码

一、新建一调用工程项目和一个要测试的类项目,首先设计好测试的类以及函数,然后编译生成对应的类名.DLL文件。然后复制到调用工程项目的BIN目录下。   二、在调用工程项目中新建一WINFORM窗体...
  • xqf222
  • xqf222
  • 2012年09月15日 23:49
  • 2598

cxf下载客户端代码

到cxf官网http://cxf.apache.org/downoload.html,下载cxf的工具包 Windows环境下载zip包。 解压缩 命令: cmd: cd 到cxf工...
  • weixin_40648117
  • weixin_40648117
  • 2017年12月12日 17:58
  • 26

python 动态调用python 代码

import sys import StringIO # create file-like string to capture output codeOut = StringIO.StringIO(...
  • majinfei
  • majinfei
  • 2014年04月17日 10:06
  • 369

浅谈WebService开发三(动态调用WebService)

在前两讲里,我已经向大家演示了如何使用WebService、同步,异步调用WebService,而在实际开发过程中,可能会有多个WebService接口供你选择,而在程序执行过程中才决定使用哪一个We...
  • wayne20018891
  • wayne20018891
  • 2012年06月03日 17:42
  • 2550

LabVIEW 的动态调用

如果程序中所使用的VI较多,且有些VI很大并属于基本上不太常用的VI,为避免占用内存的使用或减少程序的导入时间,也可以进行VI的动态调用。所谓动态调用是指在程序运行需要时再调入,运行完成后从内存中将其...
  • txpp520
  • txpp520
  • 2017年06月26日 10:11
  • 695

使用CXF实现WebService,并在客户端实现动态调用

WebService实现 1、 整个项目使用CXF来实现,在实现的过程中,在MyEclipse中对CXF下lib中的所有jar文件通过引入外部包来处理。 2、 在MyEclipse6.5中可以实现...
  • gm_163
  • gm_163
  • 2013年05月31日 17:43
  • 1545

动态调用WebService(C#) (非常实用)

通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务。这样是使工作简单了,但是却和提供Web服务的URL、方法名...
  • ysq5202121
  • ysq5202121
  • 2011年11月07日 11:32
  • 22838

如何动态调用WebService?

今天在CSDN看到一个问题:如何动态调用WebService? (原贴见:http://community.csdn.net/Expert/topic/3330/3330006.xml?temp=.8...
  • fangxinggood
  • fangxinggood
  • 2005年06月02日 13:14
  • 10013

开发:随笔记录之 CXF 动态调用Webservice

public class WebServiceUtil2 { static Logger log = Logger.getLogger(WebServiceUtil2.class); ...
  • shijing266
  • shijing266
  • 2014年04月25日 11:55
  • 2293
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再比较动态调用代码
举报原因:
原因补充:

(最多只允许输入30个字)