IronPython和C#执行速度对比

开发 后端
其实我自己对执行速度这个问题本来并没有什么兴趣,因为以前的经验告诉我:除非是运算密集型的程序,否则脚本语言和编译型语言使用起来速度没有多大差别。但是我们公司有个人知道我的想法以后,天天在我耳边嚷嚷脚本运行速度太慢,那好吧,让我用实验来说服你。不过这一试,还真的出现了吓人一跳的结果。

我构思的实验覆盖到下面几个我认为是实际项目中比较有代表性的场景:

1.访问一个稍大的数据表,遍历所有记录;

2.生成并操作一个列表;

3.生成并操作一个字典;

4.通过反射动态加载并调用一个方法。

C#部分的代码,编译时使用了/debug-和/optimize+:

Code

  1. usingSystem;  
  2. usingSystem.Data.SqlClient;  
  3. usingSystem.Diagnostics;  
  4. usingSystem.Collections.Generic;  
  5. usingSystem.Reflection;  
  6.  
  7. namespaceTest  
  8. {  
  9. classTest  
  10. {  
  11. publicstaticvoidMain(string[]args)  
  12. {  
  13. Console.WriteLine("C#:");  
  14. Measure(TestDb,"TestDb");  
  15. Measure(TestList,"TestList");  
  16. Measure(TestDict,"TestDict");  
  17. Measure(TestReflection,"TestReflection");  
  18. }  
  19.  
  20. delegatevoidFuncDelegate();  
  21.  
  22. staticvoidMeasure(FuncDelegatefunc,stringfuncName)  
  23. {  
  24. Stopwatchsw=newStopwatch();  
  25. sw.Start();  
  26. func();  
  27. sw.Stop();  
  28. Console.WriteLine("{0}used{1}ms",funcName,sw.ElapsedMilliseconds);  
  29. }  
  30.  
  31. staticvoidTestDb()  
  32. {  
  33. using(SqlConnectionconn=newSqlConnection(connStr))  
  34. {  
  35. conn.Open();  
  36.  
  37. SqlCommandcmd=newSqlCommand(sql,conn);  
  38. SqlDataReaderreader=cmd.ExecuteReader();  
  39. while(reader.Read())  
  40. {  
  41. varid=reader["Id"];  
  42. varcode=reader["Code"];  
  43. varcargoCode=reader["CargoCode"];  
  44. varlength=reader["Length"];  
  45. varwidth=reader["Width"];  
  46. varheight=reader["Height"];  
  47. varvol=reader["Vol"];  
  48. varpallet=reader["Pallet"];  
  49. }  
  50. reader.Close();  
  51. cmd.Dispose();  
  52. conn.Close();  
  53. }  
  54. }  
  55.  
  56. staticvoidTestList()  
  57. {  
  58. varlist=newList();  
  59. constintcount=100000;  
  60. for(inti=0;ilist.Add(string.Format("item{0}",i));  
  61. for(inti=count-1;i>=0;i--)  
  62. list.RemoveAt(i);  
  63. }  
  64.  
  65. staticvoidTestDict()  
  66. {  
  67. vardict=newDictionary();  
  68. constintcount=100000;  
  69. for(inti=0;idict[string.Format("key{0}",i)]=string.Format("value{0}",i);  
  70. for(inti=0;idict.Remove(string.Format("key{0}",i));  
  71. }  
  72.  
  73. staticvoidTestReflection()  
  74. {  
  75. AssemblyAssemblyassem=Assembly.LoadFrom("Lib.dll");  
  76. Typetype=assem.GetType("Lib.TestLib");  
  77. constintcount=100000;  
  78. ConstructorInfoci=type.GetConstructor(Type.EmptyTypes);  
  79. MethodInfomi=type.GetMethod("GetMessage");  
  80. for(inti=0;i{  
  81. objectobj=ci.Invoke(null);//Activator.CreateInstance(type);  
  82. mi.Invoke(obj,newobject[]{"name"});  
  83. }  
  84. }  
  85.  
  86. conststringconnStr="IntegratedSecurity=SSPI;InitialCatalog=test;DataSource=.";  
  87.  
  88. conststringsql="select*fromCargoPackageTypes";  
  89. }  

IronPython部分的代码:

Code

  1. from__future__importwith_statement  
  2. importclr,sys  
  3. clr.AddReference('System.Data')  
  4. fromSystem.Data.SqlClientimportSqlCommand,SqlConnection  
  5. fromSystem.DiagnosticsimportStopwatch  
  6. fromSystem.ReflectionimportAssembly  
  7.  
  8. connStr="IntegratedSecurity=SSPI;InitialCatalog=test;DataSource=.";  
  9.  
  10. sql="select*fromCargoPackageTypes";  
  11.  
  12. deftestDb():  
  13. withSqlConnection(connStr)asconn:  
  14. conn.Open()  
  15.  
  16. cmd=SqlCommand(sql,conn)  
  17. reader=cmd.ExecuteReader()  
  18. whilereader.Read():  
  19. id=reader["Id"]  
  20. code=reader["Code"]  
  21. cargoCode=reader["CargoCode"]  
  22. length=reader["Length"]  
  23. width=reader["Width"]  
  24. height=reader["Height"]  
  25. vol=reader["Vol"]  
  26. pallet=reader["Pallet"]  
  27. reader.Close()  
  28. cmd.Dispose()  
  29. conn.Close()  
  30. deftestList():  
  31. lst=[]  
  32. count=100000 
  33. foriinxrange(count):  
  34. lst.append('item%d'%i)  
  35. foriinxrange(count-1,-1,-1):  
  36. lst.pop(i)  
  37. deftestDict():  
  38. d={}  
  39. count=100000 
  40. foriinxrange(count):  
  41. d['key%d'%i]='value%d'%i  
  42. foriinxrange(count):  
  43. d.pop('key%d'%i)  
  44. deftestReflection():  
  45. clr.AddReferenceToFile('Lib.dll')  
  46. fromLibimportTestLib  
  47. count=100000 
  48. foriinxrange(count):  
  49. obj=TestLib()  
  50. obj.GetMessage('name')  
  51. defmeasure(fn):  
  52. sw=Stopwatch()  
  53. sw.Start()  
  54. fn()  
  55. sw.Stop()  
  56. print'%sused%sms'%(fn.__name__,sw.ElapsedMilliseconds)  
  57. print'Python:'  
  58. measure(testDb)  
  59. measure(testList)  
  60. measure(testDict)  
  61. measure(testReflection) 

运行结果:

运行结果

对于列表和字典的操作,IronPython比C#慢3到4倍,这是意料之中的事情。没有想到的是访问数据库的方法,IronPython竟然比C#还要略快,这是事先无论如何都没有料到的。原来我以为,数据库访问代码基本上是纯粹的调用ADO.Net,瓶颈主要是在数据库那一边,IronPython在方法调用的时候应该比C#略微慢一点吧,那么总体速度也应该稍微慢一点才对。没想到结果正好反过来!我也没有办法解释为什么这里IronPython能够做到比C#还快。不过结论应该很明显了:访问数据库的时候,你无需担心IronPython不够快。我们的项目大多数时候效率瓶颈都是出在数据库上面,至于程序语言快一点还是慢一点通常无关紧要,更何况这里的结果表明脚本语言有时候反而可能更快呢。

对于反射的测试,IronPython则是压倒性的战胜了C#。需要说明的一点是我在C#中反射生成对象使用的方法是ConstructorInfo.Invoke()。如果换成Activator.CreateInstance()的话,那么C#的时间将会缩减到230~250毫秒,不过即便这样仍然比IronPython落后一半左右。为什么使用反射时IronPython比C#快这么多呢?或许因为它运行的时候能够在内存中动态生成部分字节码,从而跳过反射环节,所以更快吧。

从这个实验的结果看,IronPython的性能可以说好到超出了我的预期。因为之前也看过其他一些相关的性能评测,比如说Ruby要比Java的运行速度慢30倍(这个比较已经有一段时间了,现在差距应该有所缩小),相比之下IronPython的性能简直可以用十分优异来形容了。当然脚本语言也有一个不足的地方,就是加载解释器的时候会带来几秒钟的固定开销,频繁修改程序的时候,这几秒钟还是有点让人难受的。好在以嵌入方式使用IronPython的时候,引擎只需要加载一次就够了,所以这个缺点大体上还是可以接受的。

【编辑推荐】

  1. C#中使用位运算来实现权限管理
  2. 浅谈C#如何实现多继承
  3. 浅谈C#基元类型及常见问题解答
  4. C#语言与Java语言程序的比较
  5. 利用C#指针进行图像操作
责任编辑:彭凡 来源: cnblogs
相关推荐

2010-04-27 18:54:06

AIX语言

2009-08-17 16:34:21

.NET分布式缓存Memcached

2009-08-28 17:18:55

foreach循环

2009-04-28 10:23:58

VB.NETC#对比

2023-05-10 08:29:12

2009-09-07 10:37:32

C#执行Finaliz

2018-08-02 16:17:34

Python 开发编程语言

2009-08-18 14:14:45

C#扩展方法性能测试

2011-07-04 10:19:41

索引ONLINE

2022-02-09 07:13:52

C盘爆满存储文件硬盘

2009-08-06 09:32:03

C#代码协同执行

2009-08-17 10:54:53

C#执行ping命令

2009-08-27 16:11:03

C# delegateC# event

2009-08-13 17:04:09

C#语言C#程序

2009-08-11 09:10:26

Windows 7系统提速

2009-10-15 09:32:39

什么是IronPythPython.NET

2009-09-07 15:21:38

Java与C#事件处理

2023-07-06 14:49:44

PandasPolars语法

2009-08-26 10:34:15

C#类型C#变量
点赞
收藏

51CTO技术栈公众号