.NET 代码编译还是复杂化?

发布于 2024-08-20 05:40:51 字数 203 浏览 3 评论 0原文

Q1) 为什么 C# 最初编译为 IL,然后在运行时进行 JIT 编译并在虚拟机上运行(?)。还是 JIT 符合本机机器代码?

Q2) 如果第二个为真(JIT 符合本机机器代码),那么代码运行的 .NET 沙箱在哪里?

Q3) 另外,为什么代码首先要编译为 IL?为什么不直接编译为本机机器代码呢? MS 有一个名为 ngen 的工具,但为什么它是可选的?

Q1) Why is C# initially compiled to IL and then at runtime JIT complied and run on top of a virtual machine(?). Or is it JIT complied to native machine code?

Q2) If the second is true (JIT complied to native machine code), then where is the .NET sandbox the code runs under?

Q3) In addition, why is the code compiled to IL in the first place. Why not simply compile to native machine code all the time? There is a tool from MS from this called ngen but why is that optional?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清晨说晚安 2024-08-27 05:40:51

当进程运行时,IL 被 JIT(JIT = Just In Time)编译为本机机器代码。

虚拟机层的使用允许 .NET 在跨平台上以一致的方式运行(例如,无论您运行在 32 位还是 64 位机器上,int 始终是 32 位,而 C++ 则不是这种情况) )。

JIT 编译允许优化在代码运行时动态调整自身(例如,对频繁调用的代码位应用更积极的优化,或利用特定机器上可用的硬件指令,如 SSE2),这是您无法做到的静态编译器。

The IL is JIT'd (JIT = Just In Time) compiled to native machine code as the process runs.

The use of a virtual machine layer allows .NET to behave in a consistent manner across platforms (e.g. an int is always 32 bits regardless of whether you're running on a 32- or 64- bit machine, this is not the case with C++).

JIT compiling allows optimisations to dynamically tailor themselves to the code as it runs (e.g. apply more aggressive optimisations to bits of code that are called frequently, or make use of hardware instructions available on the specific machine like SSE2) which you can't do with a static compiler.

牵你手 2024-08-27 05:40:51

A1) JIT 编译为本机机器代码

A2) 在 .net 中,没有沙箱这样的术语。有 AppDomains 代替。它们作为 CLR 的一部分运行(即作为可执行进程的一部分)

A3) Jeffrey Richter 的 NGen 缺点:

  • NGen 的文件可能会不同步。
    当 CLR 加载 NGen 的文件时,它会比较
    有关先前编译的代码和当前执行的特征的数量
    环境。如果任何特征不匹配,则无法生成 NGen 文件
    使用,并使用正常的 JIT 编译器进程。

  • 加载时间性能较差(变基/绑定)。
    程序集文件是标准的 Windows PE 文件,因此每个文件都包含一个首选基地址。许多窗户
    开发人员熟悉有关基址和变基的问题。当 JIT 编译代码时,这些问题不是问题,因为正确的内存地址引用是在运行时计算的。

  • 执行时间性能较差。
    编译代码时,NGen 无法生成那么多
    JIT 编译器可以对执行环境进行假设。这导致
    NGen.exe 产生劣质代码。例如,NGen 不会优化使用
    某些CPU指令;它添加了静态字段访问的间接寻址,因为实际的
    静态字段的地址直到运行时才知道。 NGen 插入代码来调用类
    构造函数无处不在,因为它不知道代码执行的顺序
    如果已经调用了类构造函数。

A1) JIT compiles to native machine code

A2) In .net there is no such term as sandbox. There is AppDomains instead. And they runs as part of CLR (i.e. as part of executable process)

A3) NGen drawbacks from Jeffrey Richter:

  • NGen'd files can get out of sync.
    When the CLR loads an NGen'd file, it compares a
    number of characteristics about the previously compiled code and the current execution
    environment. If any of the characteristics don't match, the NGen'd file cannot be
    used, and the normal JIT compiler process is used instead.

  • Inferior Load-Time Performance (Rebasing/Binding).
    Assembly files are standard Windows PE files, and, as such, each contains a preferred base address. Many Windows
    developers are familiar with the issues surrounding base addresses and rebasing. When JIT compiling code, these issues aren't a concern because correct memory address references are calculated at run time.

  • Inferior Execution-Time Performance.
    When compiling code, NGen can't make as many
    assumptions about the execution environment as the JIT compiler can. This causes
    NGen.exe to produce inferior code. For example, NGen won't optimize the use of
    certain CPU instructions; it adds indirections for static field access because the actual
    address of the static fields isn't known until run time. NGen inserts code to call class
    constructors everywhere because it doesn't know the order in which the code will execute
    and if a class constructor has already been called.

南笙 2024-08-27 05:40:51

您可以使用 NGEN 创建本机版本您的 .NET 程序集。这样做意味着 JIT 不必在运行时执行此操作。

.NET 首先编译为 IL,然后编译为本机,因为 JIT 旨在针对运行代码的当前 CPU 优化 IL 代码。

.NET 代码被编译为 IL 以实现兼容性。由于您可以使用 C#、VB.NET 等创建代码,因此 JIT 需要通用指令集 (IL) 才能编译为本机代码。如果 JIT 必须了解语言,那么当新的 .NET 语言发布时,JIT 就需要更新。

我不确定沙箱问题,我最好的猜测是 .NET 应用程序与 3 个应用程序域一起运行。一个域包含 .NET 运行时(mscorlib、system.dll 等),另一个域包含您的 .NET 代码,我不记得另一个域的用途。
查看 http://my.safaribooksonline.com/9780321584090

You can use NGEN to create native versions of your .NET assemblies. Doing this means that the JIT does not have to do this at runtime.

.NET is compiled to IL first and then to native since the JIT was designed to optimize IL code for the current CPU the code is running under.

.NET code is compiled to IL for compatability. Since you can create code using C#, VB.NET, etc then the JIT needs a common instruction set (IL) in order to compile to native code. If the JIT had to be aware of languages, then the JIT would need to be updated when a new .NET language was released.

I'm not sure about the sandbox question, my best guess is that a .NET app runs with 3 application domains. One domain contains the .NET runtimes (mscorlib, system.dll, etc), another domain contains your .NET code, and I can't recall what the other domain's for.
Check out http://my.safaribooksonline.com/9780321584090

旧城空念 2024-08-27 05:40:51

1. C# 被编译为 CIL(或 IL),因为它与其他 .NET 语言共享一个平台(这就是为什么您可以用 C# 编写 DLL 并在 VB.NET 中使用它)或 F#,毫无麻烦)。然后,CLR 会将代码 JIT 编译为本机机器代码。

.NET 还可以在多个平台上运行(*NIX 和 OS X 上的 Mono)。如果 C# 编译为本机代码,这将不会那么容易。

2.没有沙箱。

3.包含在#1的答案中

1. C# is compiled in to CIL (or IL) because it shares a platform with the rest of the .NET languages (which is why you can write a DLL in C# and use it in VB.NET or F# without hassle). The CLR will then JIT Compile the code into Native Machine Code.

.NET can also be run on multiple platforms (Mono on *NIX and OS X). If C# compiled to native code, this wouldn't be nearly as easy.

2. There is no sandbox.

3. Covered in the answer to #1

寂寞花火° 2024-08-27 05:40:51

A1) 这样它就可以与平台无关(Windows、Linux、Mac),并且还可以针对您当前的硬件使用特定的优化。当它被 JIT 编译时,它就是机器代码。

A2) 整个框架(.NET 框架)都是沙箱,因此您可能通过应用程序进行的所有调用都将通过 .NET 框架沙箱。

A3) 与答案 1 一样,它允许 .NET 二进制文件在不同的平台上工作,并在客户端计算机上动态执行特定的优化。

A1) This way it's platform agnostic (Windows, Linux, Mac) and it can also use specific optimizations for your current hardware. When it gets JIT compiled it's to machine code.

A2) The whole framework (the .NET framework) is all sandbox so all calls you might make through your app will go through the .NET framework sandbox.

A3) As in answer 1, it allows the .NET binary to work in different platforms and perform specific optimizations in the client machine on the fly.

鲜肉鲜肉永远不皱 2024-08-27 05:40:51

编译后的.Net 代码成为IL,它是一种中间语言,其方式与Java 的目标代码完全相同。是的,可以使用 NGen 工具生成本机机器代码。 NGen 将生成的本机映像绑定到计算机,因此将 ngen 的二进制文件复制到不同的系统不会产生预期的结果。编译为中间代码允许做出运行时决策,而这些决策是使用 C++ 等静态类型语言无法(轻松)做出的,它还允许代码在不同的硬件架构上运行,因为代码随后在硬件架构中变得具有描述性。感觉它还以与位(例如 32 或 64)无关的方式描述了应该发生的事情的意图,而不是仅适用于 32 位系统或 64 位系统但不能同时适用于两者的机器特定代码。

另外,NGen 是可选的,因为正如我所说,它将二进制文件绑定到系统,当您需要编译机器代码的性能和动态类型语言的灵活性并且您知道二进制文件不会移动到系统时,它会很有用。一个不受其约束的系统。

Compiled .Net code becomes IL which is an intermediate language in the exact same way as that of Javas' object code. Yes it is possible to generate native machine code using the NGen tool. NGen binds the resulting native image to the machine, so copying the ngen'd binary to a different system would not produce expected results. Compiling to intermediate code allows for runtime decisions that can be made that otherwise can't (easily) be made with a staticly-typed language like C++, it also allows the functioning of code on different hardware archetectures because the code then becomes descriptive in the sense that it also describes the intent of what should happen in a bit (eg 32 or 64)-agnostic way, as opposed to machine-specific code that only works on 32-bit systems or 64-bit systems but not both.

Also, NGen is optional because as I said it binds the binary to the system, it can be useful when you need the performance of compiled machine code with the flexibility of a dynamically typed language and you know that the binary won't be moving to a system it's not bound to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文