知乎问题之:.NET AOT编译后能替代C++吗?
标题上的Native库是指:Native分为静态库(
作者:nscript
链接:https://www.zhihu.com/question/536903224/answer/2522626086

(1)开发 NDK 库有人进行尝试:NativeAOT-AndroidHelloJniLib (https://github.com/josephmoresena/NativeAOT-AndroidHelloJniLib) 通过修改 .Net Runtime 来生成 Android 下的 NDK Native 库。希望后续官方能直接支持。
(2)Remobjects Elements (https://www.remobjects.com/elements/) 收费工具。可以采用 C# 语言开发 NDK Native 库,限制是不能自由使用 Core CLR,而是使用 Remobjects 的平台相关库 island 和跨平台库 RTL,RTL 库和 Core CLR 的相关类型接口相似。
Remobjects Elements 也可以用 C# 开发 wasm 模块,试用了下,满小巧的,gzip 下可以做到低于 1M,性能测试大约是 .net 6 的1/4-1/5。同上面一样,库这块会受到限制。
Remobjects Elements 的思路蛮有意思的,可以用 C#[或 Oxygene(Object Pascal), Swift, Java, Go or Mercury (VB)] 来写各种库或应用程序。Swift 语言的免费,其他的收费。可以用这些语言写native 程序、 .net 程序、 jvm 程序 ……
----
补充一下,这是个很值得探讨的问题,我一直在尝试用 csharp 代替 cpp。很多地方可以直接替代掉,但也遇到了一些问题:
(1)写底层算法或库的话,而调用者各种语言都有,csharp的,vb的,java 的,delphi 的都碰到过。那时的工作流程是,csharp 写算法,验证之后,再根据对方需求,改成 cpp。有 AOT 之后,这种情况可以避免掉。
(2)移动开发:安卓开发底层的库,参考资料太少。比如,开发个 sdk,给 java 调用,xamarin 资料太少,解决方案也不通用。
AOT 工具链完善后,对我来说,可以解决很多问题:
(1)写底层库:可以完全放心大胆的用 csharp 写底层库了,jit 模式下快速开发,aot 模式发布。csharp 的生产力比 cpp 高太多,构建系统也比 cmake 好使的多。我现在正在尝试优化 csharp 脚本开发 aot dll 的开发流程,目前还没完全完成,但也挺舒服的,以一个最简单的例子来说明,
lib.csx:
using System.Runtime.InteropServices;
[UnmanagedCallersOnly(EntryPoint = "add")]
public static int Add(int a, int b)
{
return a + b;
}
[DllImport("pack/out/lib.dll")]
private static extern int add(int a, int b);
int result = add(2,4);
Console.WriteLine(result);
一行命令就编译成 dll 了,win10下是964 k。
nscript pack --aot --lib lib.csx
再用下面指令调用脚本:
nscript .\lib.csx
输出:
6
这种开发模式可比写 cpp 舒服太多了。目前 aot 工具链还不够完善,但是开发起来难度不大,就是工作量的问题。比如,根据代码,直接生成各个语言的调用封装,生成文档 ......
这样一来,就可以用 csharp 快速开发出底层库,生成动态链接库、静态链接库给桌面用,给服务器用,给移动设备用。底层库一般不牵扯到ui,其通用性极强。做 android 的 ndk 开发太折腾,cpp 开发,jni 调用,调试麻烦得很。
这也可以解决 csharp 这块防止反编译的问题,发布时也可以 UI 层用 jit 跑,底层用 aot 跑来保护代码。
(2)开发小工具
我造过一个轮子,把 avalonia 的控件库的核心给拆出来,用 direct2d 来绘制,弄了一些基本的控件,写简单的桌面程序,aot 之后尺寸可以控制在 4M,如果写一些小工具还是可以的。
再比如说,如果想发布一些 server 端小工具,以 http 方式提供服务,jit 模式下,用 asp.net 来做,单个文件发布压缩之后可以做到20-30M, 用 EmbedIO 来写的话,单个文件发布,win下11M,linux 下 13M。EmbedIO用了反射,aot 我没配好,没跑出来,根据经验的话,aot 应该可以做到 2-4 M。不过,11M 也够用了,来看看用脚本写的代码:
#r "nuget: EmbedIO, 3.4.3"
using EmbedIO;
using EmbedIO.WebApi;
using EmbedIO.Actions;
using EmbedIO.Files;
WebServer CreateWebServer(string url)
{
var server = new WebServer(o => o
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithLocalSessionManager()
.WithStaticFolder("/static/", "./webroot", true, m => m.WithContentCaching(true)) // Add static files after other modules to avoid conflicts
.WithModule(new ActionModule("/api", HttpVerbs.Get, HandleApi))
.WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Hello!" })))
;
return server;
}
Task HandleApi(IHttpContext ctx)
{
return ctx.SendDataAsync("api");
}
//@main
var url = "http://*:5000/";
var server = CreateWebServer(url);
server.RunAsync();
Console.ReadKey();
所以,工具链完善后,用 csharp 写东西很爽的:
(1)写完之后,AOT一下,给各个语言用 <--> 对标 cpp;
(2)写完之后,打包个几M 的小东西,扔服务器跑 <--> 是不是很像 golang?
(3)不建项目,像我上面那样用脚本写 <--> python;
(4)正常使用 <--> java;
(5)上 blazor <--> js。
除此之外,还有很新东西可以玩的 ......
----
一些场景替代不了:
(1)带 gc 的 .net aot,最小尺寸差不多1M,对于有的场景这个尺寸过大。比如说,对于插件系统,每个插件1M,100个就100M,过大,并且全部加载的话,有100个gc在跑,浪费。不知有没技术让100个插件共享一个 gc。虽然可以不开gc,但这样,就只是个大号的C了。
(2)对实时性要求高的场景,因为有gc存在会受到限制。
其他场景可以当有 gc 的 cpp 用,应该可以达到 cpp 80%+的性能。
其实现在jit,aot以及源生cpp性能都差不了太多,我做过密集计算的测试,细节忘记了,只记得是个 float 密集计算,java 的性能大于csharp和cpp。后来分析,jvm 做了向量化并行处理,csharp和cpp没有做。改csharp代码手动用simd,最后性能略高于Java。
aot的除了启动快,还有其他好处:(1)代码很难反编译;(2)尺寸小。
假设你要写个东西,给java调用或python调用,用 jit 的话,得几十M,aot 的话,可以做到 1M。这样的话,很多用cpp写的sdk,可以用csharp来写,aot编译成动态链接库,提供给上层用。
而不开gc的话,你可以就当他是个C语言的方言。
Windows以lib后缀名,Linux以a后缀 名)和动态库(Windows以dll为后缀名,Linux以so后缀名。 本文顺序先从生成Native程序.然后是动态库,最后是静态库。
知乎问题之:.NET AOT编译后能替代C++吗?的更多相关文章
- JIT和AOT编译详解
JIT和AOT编译介绍 JIT - Just-In-Time 实时编译,即时编译 通常所说的JIT的优势是Profile-Based Optimization,也就是边跑边优化 ...
- Java编译后产生class文件的命名规则
今天刚好有同学问了下Java编译后产生的.class文件名的问题,虽然一直都在使用Java做开发,但是之前对编译后产生的.class文件名的规范也基本没做了解过,也真的是忏愧啊!今天无论如何都要总结下 ...
- Idea中包内中的置文件如何发布到编译后的目录中去
1.问题引入: 运行一个maven+springmvc+hibernate的项目的时候出现了下边的错误: Caused by: java.io.FileNotFoundException: class ...
- 查看eclipse web项目中jsp编译后的servlet源文件【转】【JSP】
eclipse中,jsp编译后 servlet源文件的位置为: F:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wor ...
- Intellij如何设置编译后自动重新加载class文件?
前段时间突然发现Intellij不能自动重新加载类了,每次编译后都要重新启动项目,才能显示更新效果,后来网上查询Intellij下如何配置热部署,都说是要配置构件,然后在web容器的编辑页面选择upd ...
- Android APP使用NDK编译后的ffmpeg库出现undefined reference to 'posix_memalign'错误
在android程序中使用NDK编译后的ffmpeg库的时候出现了如下错误: jni/libs/libavutil.a(mem.o): in function av_malloc:libavutil/ ...
- java编译后字节码解析
java编译后字节码解析 参考网摘: https://my.oschina.net/indestiny/blog/194260
- VS 设置编译后的程序可以以管理员身份运行
1.首先,创建一个文件命名为 XXX.exe.manifest, 并将以下内容复制到文件 <?xml version="1.0" encoding="UTF-8&q ...
- c#:Reflector+Reflexil 修改编译后的dll/exe文件
不知道大家有没有这样的经历:现场实施时测试出一个bug,明明知道某个dll/exe文件只要修改一二行代码即可,但手头没有开发环境,紧急情况下,可以用reflector + reflexil 临时直接修 ...
随机推荐
- 我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言:一个Bug 没想到一个Bug,竟然搞我两次! 我大抵是卷上瘾了,横竖都睡不着,坐起来 ...
- 细说GaussDB(DWS)复杂多样的资源负载管理手段
摘要:对于如此多的管控功能,管控起来实际的效果到底如何,本篇文章就基于当前最新版本,进行效果实测,并进行一定的分析说明. 本文分享自华为云社区<GaussDB(DWS) 资源负载管理:并发管控以 ...
- 全国降雨侵蚀力因子R值
数据下载链接:百度云下载链接 降雨侵蚀力因子其实是反应降雨对土壤侵蚀的潜在能力,就是降雨的冲刷对土壤的侵蚀效应. 在过去几天查阅文献资料的过程中,本人亲眼看见过的关于因子R的计算方法就超过30种 ...
- 2020 CSP-J 初赛解析
题面 老师给的解析 自己觉得很好的一篇题解 直接说重点题吧,不耽误时间了 T5: 这个很显然就是让进这个 while 的次数尽可能少, 那么我们可以让他只进一次 while,即让第一次进 whil ...
- 5-2 SpringCloud | 微服务
服务器端项目演进 服务器初期状态 最早的服务器就是安装部署了一些静态页面 功能非常单一,只能做信息的呈现和输出 服务器动态页面 后来因为业务和技术的发展,页面连接了数据库,页面中大部分数据来自于数据库 ...
- Solution -「简单 DP」zxy 讲课记实
魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...
- VGA设计(原理说明。Verilog代码实现,仿真结果)
各类显示屏的显示原理大部分是利用人眼的视觉暂留效应.比如之前的数码管显示就是设计每个周期内各个小段按顺序显示,来达到显示一个数字的效果. VGA同理,显示屏在显示时是一个像素一个像素地显示,在人眼看来 ...
- 【做题笔记】CF Edu Round 132
1. 前言 本人第一次把 Div2. D 切了,开心. C 不会,寄. 后来在场外想到一种奇怪做法 AC 了. 2. 正文(A-D) CF 比赛链接 A. Three Doors 签到题.循环查找手中 ...
- NOI / 1.2编程基础之变量定义、赋值及转换全题详解(5063字)
目录 01:整型数据类型存储空间大小 02:浮点型数据类型存储空间大小
- Dubbo源码(二) - SPI源码
前情提要 假设你已经知道Dubbo SPI的使用方式,不知道的请出门左转: Dubbo源码(一) - SPI使用 Dubbo源码地址: apache/dubbo 本文使用版本:2.6.x 测试Demo ...