加载 50 万行 .net 应用程序需要多长时间?
假设我有一个用本机 C++ 编写的应用程序(超过 50 万行代码),并且我想将其移植到 .NET (C#)。我担心的一件事是 JIT 编译器。我的本机代码编译器需要 30 多秒才能完成编译。这是否意味着每次用户启动我的 C# 应用程序时,仅仅加载它就需要很长时间(因为 JIT 编译器每次都必须编译它)?
Suppose I have an application written in native C++ (over 500k lines of code) and I want to port it to .NET (C#). One thing I'm worried about is the JIT compiler. It takes my native code compiler over 30 seconds to compile. Does that mean that each time the user starts my C# app, it's going to take that long just to load it (since the JIT compiler has to compile it every time)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
JIT 编译器并不完全是您所想的意义上的“编译”。它根据需要将一种指令集(IL 字节码)转换为另一种指令集(x86 或 x64 机器代码)。根据设计,转换非常简单,并且所需时间远不及 C++ 编译应用程序所需的时间。它通常不会同时发生(“及时”意味着指令在“执行”时被翻译),因此应用程序会很快启动。
编译过程中最困难且耗时的部分是从人类可读指令(源代码)到机器可读指令(字节码或本机代码,具体取决于您的语言/平台)的转换。该部分在创建 EXE 时就已经完成,不需要重做,除非源代码(或其含义)发生变化。
The JIT compiler isn't quite "compiling" in the sense you're thinking. It's converting one instruction set (IL bytecode) to another (x86 or x64 machine code) on demand. The conversion's pretty straightforward, by design, and doesn't take anywhere near as long as C++ takes to compile an app. It doesn't even normally happen all at once ("Just in time" means the instructions are translated at about the time they're "executed"), so the app will start pretty quickly.
The hard and time-consuming part of compilation is the conversion from human-readable instructions (source code) to machine-readable ones (bytecode or native code, depending on your language/platform). That part is already done when the EXE is created, and doesn't need to be redone unless the source code (or its meaning) changes.
.NET 程序集加载器将按需加载程序集。它们已经准备好在 CLR 虚拟机字节码中运行。发生的任何 JIT 都被设计为根据调用的代码路径按需且零碎地发生。 (换句话说,小的快速块。而且它甚至可能不会发生在所有代码上。)
我不会担心 JIT。确保应用程序是模块化的,并熟悉分析工具,以便在遇到速度减慢时识别它们。
The .NET assembly loader will load assemblies on demand. They are already ready to run in the CLR virtual machine bytecode. Any JIT that happens, is designed to happen also on-demand and piecemeal based on what code paths are called. (in other words, small fast chunks. And it might not even happen on all code.)
I wouldn't worry about the JIT. Make sure the application is modular, and become familiar with the profiling tools to identify slowdowns when you experience them.
您的应用程序将立即开始运行,JIT 编译器在调用之前不会编译代码,而不是全部预先编译。其次,如果您的应用程序启动时间太慢,那么您可能需要研究 Ngen,它在本机图像缓存中编译和存储程序集。
Your app will start running right away the JIT compiler doesn't compile code until it is called, not all up front. Second if your application startup time is too slow then you might want to look into Ngen which compiles and stores assemblies in the native image cache.
这不是 JIT 编译的工作方式。
C#应用程序将被预编译成字节码,字节码本身包含许多优化。
正如其名称所暗示的那样,JIT 编译是“Just In Time”。这意味着它仅根据需要将部分字节码编译为本机代码,而不是整个应用程序。
这样做的好处之一是,运行时分析可以提高长时间运行的应用程序的性能。
That's not the way JIT compilation works.
The C# app will be pre-compiled into a bytecode, which itself contains many optimizations.
The JIT compilation is, as implied in the name, "Just In Time". That means it only compiles portions of the bytecode into native code as needed, rather than the entire application.
One upshot of this is that runtime analysis can improve performance over long-running applications.
对于一些长时间运行的 CPU 密集型应用程序来说,JIT 实际上具有性能优势*。
1) 类方法按照首次使用的顺序进行 JIT
2)对于许多应用程序将提高代码局部性(减少CPU缓存未命中)
* - 具有这些品质的应用程序往往是服务器端的
但是如果您关心启动时间,那么NGen至少包含包含启动代码的程序集(如果可以隔离),因为启动代码通常只加载一次并且不会加载受益于按需 JIT 的本地化。
过去几年 CLR 改进的好处是缓解了一些重大的启动性能问题,例如基地址冲突(请参阅 http://msdn.microsoft.com/en-us/magazine/dd569747.aspx)以及 NGen 等工具的改进,以减少开销(应用程序安装后的 NGen 时间)已减少)。如果您使用 .NET 3.5 并担心启动时间,您可能需要在运行 32 位和 64 位时进行测量,因为在 .NET 4 之前,JIT 对于 x86/x64 具有非常不同的后端。
There is actually a performance benefit of the JIT for some long-running CPU-intensive applications*.
1) Class methods are JIT'ed in the order they are first used
2) For many applications will improve code locality (recude CPU cache misses)
* - applications with these qualities tend to be server-side
But if startup time is your concern then NGen at least the assemblies that contain the startup code (if it can be isolated), as the startup code often only loads once and won't benefit from locality of the on-demand JIT.
The nice thing about the CLR improvements over the past couple of years has been the easing of some big startup performance issues like base address collitions (see http://msdn.microsoft.com/en-us/magazine/dd569747.aspx) and improvements in tools like NGen to reduce overhead (NGen time after application install has been reduced). If you're using .NET 3.5 and worried about startup time you might want to measure when running 32-bit and 64-bit, as the JIT had very different backends for x86/x64 before .NET 4.
这取决于许多因素,并且没有足够的信息可以知道,仅给出本机代码编译器编译它所需的时间并不能提供足够的信息。根据应用程序正在执行的操作,该过程可能需要 30 秒到几小时不等。
This would depend on many factors and there is not enough information to know, just giving the time it takes for the native code compiler to compile it does not give enough information. Depending on what the application is doing, it could take anywhere from 30 seconds to hours.