图 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代码却非常不同。这似乎能很明显地看出来。 5个VB.NET编译器生成的指令代码时nop,根据微软当前文档,意思是“没有 *** 作”或者“通过”。 VB.NET IL在.locals部分声明了一个额外的局部变量,类型为int32。C# IL中则直接指向这个类。 VB.NET IL使用6个指令创建StringBuilder对象,而C#只用了5个。VB.NET指令中一个是nop。 两个for循环都用了13个指令。有趣的是,VB.NET的for循环中一个指令是nop。 有谁愿意回答以下吗? 我希望有IL的大牛能够更加深入地解释一下这里是怎么回事。 一些奇怪的事情确实不对劲。尽管这里没有确切的证据,但是确实VB.NET编译器生成代码要比对手C#稍微低效一些。这似乎支持了这个结论,至少在本例子中,C#确实比同样的VB.NET代码更加出色。因为我们正使用测试版,所以这些都可能改观。所以,我们静候进一步消息。所以可能还有下一章节继续这个问题的讨论。 原文链接:http://www.techrepublic.com/article/vbnet-vs-c-round-2-pounding-on-performance/ 总结
以上是内存溢出为你收集整理的VB.NET vs. C#, round 2: Pounding on performance--VB.NET vs C#, 第二波:效率碰撞全部内容,希望文章能够帮你解决VB.NET vs. C#, round 2: Pounding on performance--VB.NET vs C#, 第二波:效率碰撞所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)