草庐IT

c# - c# 编译器比 VB.NET 编译器更聪明吗?

coder 2024-05-30 原文

如果我查看在 Linqpad 中为以下两个代码片段创建的 IL,我想知道这里发生了什么。

在 C# 中

int i = 42;

产生以下 IL 代码

IL_0000:  ret

而在 VB 中

Dim i As Integer = 42

IL_0000:  ldc.i4.s    2A 
IL_0002:  stloc.0  

显然,c# 编译器知道该值从未被使用过,因此什么也不返回。在 VB.NET 中,翻译了实际代码。

这是由于编译器优化的差异还是其他原因造成的?

更新:只是为了澄清这一点 - 我只是将这一行输入到 LinqPad 中并查看它创建的 IL(最肯定的是通过运行相应的编译器)。 没有程序。

最佳答案

去掉 linqpad 问题,我在这些程序上用 /optimize+/debug- 运行了 vbccsc:

Module f

Public Sub Main()
    Dim i As Integer = 42
End Sub

End Module

public static class f
{

public static void Main()
{
    int i = 42;
}

}

并从 ILDASM 获得了这些 CIL 结果:

对于 VB:

.method public static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       4 (0x4)
  .maxstack  1
  .locals init (int32 V_0)
  IL_0000:  ldc.i4.s   42
  IL_0002:  stloc.0
  IL_0003:  ret
} // end of method f::Main

对于 C#:

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method f::Main

所以,,至少在这方面 cscvbc“更聪明”。但我敢打赌,JITter 会消除执行时的任何差异。

编辑

我检查了一下,实际上执行的 native 代码不同的,至少在我的系统上是这样。我在两者中都加入了 Console.ReadLine() 调用,让我有机会附加调试器,我得到了这些反汇编:

来自 VB:

00000000  sub         rsp,38h 
00000004  mov         dword ptr [rsp+20h],0 
0000000c  mov         rax,7FF000434D8h 
00000016  mov         eax,dword ptr [rax] 
00000018  test        eax,eax 
0000001a  je          0000000000000021 
0000001c  call        FFFFFFFFE45BA230 
00000021  mov         dword ptr [rsp+20h],2Ah 
00000029  call        FFFFFFFFE26ABF20 
0000002e  mov         qword ptr [rsp+28h],rax 
00000033  nop 
00000034  jmp         0000000000000036 
00000036  add         rsp,38h 
0000003a  ret 

来自 C#:

00000000  sub         rsp,38h 
00000004  mov         rax,7FF000534D8h 
0000000e  mov         eax,dword ptr [rax] 
00000010  test        eax,eax 
00000012  je          0000000000000019 
00000014  call        FFFFFFFFE45AA230 
00000019  call        FFFFFFFFE391BF20 
0000001e  mov         qword ptr [rsp+20h],rax 
00000023  nop 
00000024  jmp         0000000000000026 
00000026  add         rsp,38h 
0000002a  ret 

现在,我的 assembley 几乎不存在,但即使我也能看到

mov         dword ptr [rsp+20h],2Ah 

在 from-VB 中指的是十六进制 2A 的常量值,即十进制的 42。好了,它最终确实执行了更多指令。

关于c# - c# 编译器比 VB.NET 编译器更聪明吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9209544/

有关c# - c# 编译器比 VB.NET 编译器更聪明吗?的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  6. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. .net - .NET 将如何影响 Python 和 Ruby 应用程序? - 2

    我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth

随机推荐