VB.NET vs. C#, round 2: Pounding on performance--VB.NET vs C#, 第二波:效率碰撞

VB.NET vs C#, 第二波:效率碰撞

从效率的观点看,所有的.NET性能都一样吗?答案可能会让你大吃一惊。看看我们在深一层次研究代码时发现了什么。

如果说所有新技术在幼年成长中共享一个属性的话,那就是一大堆问题。微软的新.NET开发框架也是一样。

因此,我们决定在这里建一个区,专门回答关于.NET开发的问题。所以如果你对于微软新的开发平台有疑问的话,尽管将问题发过来,我尽力解决它。

我们接到一个关于性能的问题,是来自Vladimir Srecovic的问题。

C#性能标杆

Q:我看到过报道C#产生IL(中间语言)代码,比VB.NET产生的代码运行速度快,是真的吗?

A:我对这个问题的回答是否定的,我从来没有看到任何证据表明C#在速度上具有优势,并且认为存在任何重要的性能不同是不可能的。毕竟IL代码被相同的JIT编译器编译成自然代码,忽略是哪一个IL编译器生成的。所以至少在理论上,只要你的IL编译器符合标准,相等的VB.NET,C#或者甚至是COBOL.NET代码都将编译为基本相同的IL代码。

无论如何,这些都是传统的想法。为了更加彻底地证明,我决定用一个小实验看看这是否合理。我选择了TypeFinder样本应用程序的VB.NET和C#版本(在\Program Files\Microsoft.Net\FrameworkSDK\Samples\applications\typefinder中查看)并编译它们。下一步,我选取结果执行文件,并通过MSIL disassembler utility(\Program Files\Microsoft.Net\FrameworkSDK\Bin\ildasm.exe)查看两个编译器产生的IL。然后我比较这两片专门为相当简单的方法IndentedWriter.WriteLine产生的IL。你可以看到图A这个方法的VB.NET源,C#源在图B中。

图 A

VB.NET版本要比C#版本的稍微长一点。

图 B

C#版本用了7行代码。

当我比较最后的IL代码时,对我发现的事情大吃一惊:VB.NET版本比C#版本长9行(而且9KB)。你可以在列表A中看到VB.NET编译器产生的IL;C#编译器的结果出现在列表B中。

列表A:

.method public hidebysig instance void  WriteLine(string message) cil managed

 {
  // Code size       75 (0x4b)
  .maxstack  3
  .locals init ([0] int32 i,
           [1] class [mscorlib]System.Text.StringBuilder sb,
           [2] int32 _Vb_t_i4_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldfld      bool NetSDKSamples.IndentedWriter::myPrintFlag
  IL_0007:  brfalse.s  IL_0048
  IL_0009:  newobj     instance void [mscorlib]System.Text.StringBuilder::.ctor()
  IL_000e:  stloc.1
  IL_000f:  ldc.i4.0
  IL_0010:  ldarg.0
  IL_0011:  ldfld      int32 NetSDKSamples.IndentedWriter::myIndent
  IL_0016:  ldc.i4.1
  IL_0017:  sub.ovf
  IL_0018:  stloc.2
  IL_0019:  stloc.0
  IL_001a:  br.s       IL_002a
  IL_001c:  ldloc.1
  IL_001d:  ldc.i4.s   32
  IL_001f:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(char)
  IL_0024:  pop
  IL_0025:  nop
  IL_0026:  ldloc.0
  IL_0027:  ldc.i4.1
  IL_0028:  add.ovf
  IL_0029:  stloc.0
  IL_002a:  ldloc.0
  IL_002b:  ldloc.2
  IL_002c:  ble.s      IL_001c
  IL_002e:  ldloc.1
  IL_002f:  ldarg.1
  IL_0030:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
  IL_0035:  pop
  IL_0036:  ldarg.0
  IL_0037:  ldfld      class [mscorlib]System.IO.TextWriter NetSDKSamples.IndentedWriter::myTextWriter
  IL_003c:  ldloc.1
  IL_003d:  callvirt   instance string [mscorlib]System.Text.StringBuilder::ToString()
  IL_0042:  callvirt   instance void [mscorlib]System.IO.TextWriter::WriteLine(string)
  IL_0047:  nop
  IL_0048:  nop
  IL_0049:  nop
  IL_004a:  ret

 } // end of method IndentedWriter::WriteLine

列表B:

.method public hidebysig instance void  WriteLine(string message) cil managed

 {
  // Code size       66 (0x42)
  .maxstack  2
  .locals ([0] class [mscorlib]System.Text.StringBuilder sb,
           [1] int32 i)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      bool IndentedWriter::myPrintFlag
  IL_0006:  brfalse.s  IL_0041
  IL_0008:  newobj     instance void [mscorlib]System.Text.StringBuilder::.ctor()
  IL_000d:  stloc.0
  IL_000e:  ldc.i4.0
  IL_000f:  stloc.1
  IL_0010:  br.s       IL_001f
  IL_0012:  ldloc.0
  IL_0013:  ldc.i4.s   32
  IL_0015:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(char)
  IL_001a:  pop
  IL_001b:  ldloc.1
  IL_001c:  ldc.i4.1
  IL_001d:  add
  IL_001e:  stloc.1
  IL_001f:  ldloc.1
  IL_0020:  ldarg.0
  IL_0021:  ldfld      int32 IndentedWriter::myIndent
  IL_0026:  blt.s      IL_0012
  IL_0028:  ldloc.0
  IL_0029:  ldarg.1
  IL_002a:  callvirt   instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
  IL_002f:  pop
  IL_0030:  ldarg.0
  IL_0031:  ldfld      class [mscorlib]System.IO.TextWriter IndentedWriter::myTextWriter
  IL_0036:  ldloc.0
  IL_0037:  callvirt   instance string [mscorlib]System.Text.StringBuilder::ToString()
  IL_003c:  callvirt   instance void [mscorlib]System.IO.TextWriter::WriteLine(string)
  IL_0041:  ret

 } // end of method IndentedWriter::WriteLine

编译代码后,我简单随便比较了以下,超过12次实验发现,C#版本的FindType.exe使用反射列出属于某一特定对象的方法,险胜于VB.NET版本。后者最快时间也比前者最慢时间要慢。

这到底是怎么回事?

我不是IL的专家,当前记录也很少。但是从IL代码上看,尽管两片代码功能相同并且以相同顺序执行相同任务,但是最后的IL代码却非常不同。这似乎能很明显地看出来。

有谁愿意回答以下吗?

我喜欢

原文链接:http://www.techrepublic.com/article/vbnet-vs-c-round-2-pounding-on-performance/

时间: 2025-01-08 01:53:14

VB.NET vs. C#, round 2: Pounding on performance--VB.NET vs C#, 第二波:效率碰撞的相关文章

VB.NET在线升级程序源代码,可以独立使用

这个程序是我做一个办公管理系统的时候用到的,这里有源码,需要的亲拿去研究学习:vb.net在线升级程序: 程序实现了通过vb.net连接远程云服务器,并且从云服务器中获取更新,并且自动下载更新,升级本地客户端程序: 下载地址:UpEASoft.zip   429.56 KB

vb调用excel方法详解及操作相关操作命令大全

如果你要在VB中要想调用Excel,需要打开VB编程环境"工程"菜单中的"引用"项目,并选取项目中的"Microsoft Excel 11.0 object library"项.由于你的Excel版本不同,所以这个选项的版本号也是不同的. 因为EXCEL是以层次结构组织对象的,其对象模型中含有许多不同的对象元素.    第一层:Application对象,即Excel本身:    第二层:workbooks对象集,指Excel的工作簿文件: 第三

当VB遇上C++

最近在学习VB.NET 这块的东西,自然而然就会想到VB.NET与VB6是什么关系? 宏观上来讲就是从基于对象变成了完全的面向对象,因此不能简单的说VB.NET是VB6.0的升级版本.在学习VB.NET之前,已经接触过C++和VB,所以在学习VB.NET的时候总能看到他们的影子,那种似曾相识的感觉让我不得不仰天长叹:这VB.NET简直就是混搭版本的程序设计语言啊! 在1991年Visual Basic1.0诞生以前,开发人员不得不使用C++和Windows系统本身的未成形的程序块,即所谓的Win

VB.NET版+三层实现登陆

三层已经学了一些时间了,開始认为自己能够用C#敲代码了,就用C#写了一个实现登陆的,真正再用在机房中.还是认为非常吃力的,所以.决定用vb.net敲了.以下是我用vb.net实现的登陆.能够给大家做一些參考. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWl1bXV4aWEwOTIx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 这是构架的

【程序开发小记】VB.NET音乐播放器

写在前面的话: 为了营造一个很好的交流学习的环境,也是为了迎合学校毕业设计的需求,开通了博客园.在下学期伊始,会每星期更新毕业设计的进度.博客业已开通,为了交流学习,要只是更新毕业设计的进度显得有些做作.博主并不是好看书时写些小评的主儿,遂不知有和内容好献于此,只得将之前课程中或是实习时开发的程序在此做个简述. 因这些项目也是博主心血,也是怕某些学弟学妹直接搬用引发事端,不便将源码原封不动摆在这里,在此只做简要说明. 若有意愿交流学习,可以在评论或是私信留下联系方式. 话不多说,接下来直奔主题.

VB.NET之错误异常处理

相对于VB而言,VB.NET中引入了很多特色.当中最吸引我的就是引入了结构化异常处理. 尽管VB.NET仍然支持OnError Goto类型的异常处理,可是这样做并非非常好.相比而言,结构化异常处理更加灵活,使用更加方便.我们应该充分利用VB.NET提供的结构化异常处理. 在VB.NET结构中的异常处理分为3个语句块. (1)try块负责错误代码的捕获 (2)catch进行错误的处理 (3)finally负责错误处理后的兴许工作如:释放对象.清理资源等的工作. 使用这些区块的目的是同意执行Try

VB字符串函数集

1.      ASC,Chr函数 [说明]: 转换字符字符码 [格式]: P=Asc(X) 返回字符串X的第一个字符的字符码 P=Chr(X) 返回字符码等于X的字符 [范例]: (1)P=Chr(65)      ' 输出字符A,因为A的ASCII码等于65 (2)P=Asc("A")   ' 输出65 2.      Len函数 [格式]: P=Len(X) [说明]: 计算字符串X的长度,空字符串长度为0,空格符也算一个字符,一个中文字虽然占用2 Bytes,但也算一个字符.

VB.NET & Visual Basic

当看到VB.NET者这本书籍的时候,翻开目录唯一的感受就是:这不和VB一样吗?到底有什么区别呢? 1)版本: 重新回顾VB,可以发现其实他是Microsoft退出的基于Windows操作系统环境下的软件开发工具,是一种功能强大的高级程序设计语言. Visual指的是GUI(graphical userinterfaces)的方法.使用这种方法进行程序设计时,用户只需根据界面设计的要求,将预先建立的对象添加到屏幕上,设置他们的各种属性. Basic指的是Basic语言,VB是BASIC语言的进一步

VB.NET & Visual Basic

当看到VB.NET者这本书籍的时候,翻开文件夹唯一的感受就是:这不和VB一样吗?究竟有什么差别呢? 1)版本号: 又一次回想VB,能够发现事实上他是Microsoft退出的基于Windows操作系统环境下的软件开发工具,是一种功能强大的高级程序设计语言. Visual指的是GUI(graphical userinterfaces)的方法.使用这样的方法进行程序设计时,用户仅仅需依据界面设计的要求,将预先建立的对象加入到屏幕上,设置他们的各种属性. Basic指的是Basic语言,VB是BASIC