.Net Native

我从.Net Native中学到了什么

作者 区志为 发布于 2016年3月2日 | 讨论

本文最初发布于 Mark Rendle 的博客,经原作者授权由 InfoQ 中文站翻译并分享。”

笔者在Linux上安装了.Net Core runtime,并对新的CLI、CoreRT、ASP.Net Core进行了简单的测试与分析。

在之前文章中,我终于将整个.Net Core runtime和工具都安装到我工作用的Linux笔记本了,包括了:

(根据命名声明,从现在起我将会把 ASP.NET 5 写成 ASP.NET Core)

昨晚,我开始尝试在CoreCLR/CoreFx上运行各种当前能在Mono runtime上运行的ASP.NET Core项目。 到目前为止它们都能工作,虽然我确实将那些我认为有问题的项目留到了最后,尤其是那些使用了Azure Storage SDK中较边缘部分的项目。:)

我在台式机上尝试通过那些能同时在CoreCLR和Mono的Docker容器中运行的各种服务来执行一些负载测试,我将会在这里公开那些实验结果。

我过去的两天里挖遍了GitHub上dotnet组织的各个仓库之后,我所见到的让我感到很兴奋。当然,我说的不仅仅是在Linux上运行。

新的CLI

新的 dotnet CLI 与我大约在去年使用过的 dnx, dnudnvm 命令有很大差别。那些都是shell脚本(或Bash函数);如果你执行一下 cat `which dnx` 就能看见脚本,它用Mono运行一个.Net DLL。

但如果你执行 cat `which dotnet` 你将会得到满屏的乱码,因为dotnet是一个本机执行文件。

我不知道现在那边具体发展成怎样了。在dotnet-nightly 文件夹里翻一下,有很多大小相近的本机执行文件,这挺怪异的,或许它们只是.Net程序集的装载器,但也挺酷的。

CoreRT

由于好奇让这一切成为可能的基础,我进入了 CoreRT 仓库,里面对CoreRT的描述是这样的

一个为AOT(ahead of time compilation)场景优化的.NET Core runtime,附带.NET Native编译器工具链。

然而什么是工具链呢?

我找到了隐藏在文档目录中的intro-to-corert.md文件,其中解析了具体的情况。

这个项目的开发者(我想应该包含所有在微软内外的贡献者)正在构建一套工具,可以将MSIL byte-code(由Roslyn编译C#代码产生)预先编译成本机x86/64机器编码。

最初默认的实现使用新的64-bit CLR JIT编译器(去年夏天发布)RyuJIT来产生机器编码,但工具链还可以使用其他编译器,包括它们自己引用的IL-to-C++ compiler (难以置信的小巧) and LLILC,这个是建基于LLVM的CoreCLR中正在使用的JIT编译器,而且将来打算支持AOT编译。

关于JIT与AOT的简易备注

.NET CLR包含一个Just-In-Time (JIT)编译器负责把MSIL bytecode转换成本机机器编码。它在你应用程序运行的时候进行转换,而且它是在各方法第一次被调用的时候才进行转换的;因此,“just in time”。这就是为什么同一个程序集能够在不同的CPU和操作系统上使用。

JIT编译器,一般来说,是优化成尽可能快地完成编译,而不是产生尽可能好的机器编码。

一个Ahead-Of-Time (AOT) 编译器,能为特定的目标CPU和操作系统把所有MSIL bytecode预先转换成本机机器编码,所以你无需单独的runtime就能够分发应用或程序库。

因为AOT编译器不像JIT编译器那样有微观时间的限制,在大部分情况下能够产生更高效、优化度高的机器编码。

CoreRT自身以CoreCLR和程序库的修改版本呈现,用不同的方式进行组织,对依赖项也进行过清理。我猜测至少有些部分开启了更高效的无用代码删除(dead code elimination),使其二进制文件尽可能的小。

所有这些意味着C#即将进入Go的领地 – 一个跨平台、本地编译、带垃圾回收的编程语言。除此之外,C#当然拥有现代语言的特点,比如泛型、async/await等等。

本机ASP.NET Core

在同一个页面, Roadmap的下面,有这样的描述:

开始,我们的目标是本机可执行(又称“控制台程序”)。之后,我们将会把它扩展到包括ASP.NET 5程序…

而且除了当前ASP.NET Core网站应用的“XCOPY部署”模型 – 简单地转存一个目录树到服务器外,我们还可以期待“COPY部署”模型 – 仅转存一个单独的可执行文件。就如同一页面所述,这会导致Dockerfile看上去像下面这样:

FROM debian:jessie

EXPOSE 5000

ADD mycompiledapp.exe /  
# The .exe is just there to make a point :)

ENTRYPOINT /mycompiledapp

还不清楚这工具链是否能静态链接非.NET程序库(例如 libuv 或者 libcurl)到本机二进制文件,还是需要以动态链接.dll.so 文件的形式一并安装。两种形式,都将制成十分小巧的Docker映像,而且容器的启动也会非常快,不过,这一连串的想法很快引起了对 unikernels 的期待,.NET Native将来会否支持呢?

初步的答案,至少看上去是 “会。会支持的。”

这些项目明显都在初级阶段,所以没必要太早地兴奋过头,免得将来在roadmap上有些东西会被残忍地杀掉,但总而言之,是时候成为一个C#开发者了。

致谢:我是受Tugberk Ugurlu最近关于这方面的部落文章激发才跳入这个兔子窝的。

原文链接https://blog.rendle.io/what-ive-learned-about-dotnet-native

This entry was posted in 未分类. Bookmark the permalink.

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s