V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rv54ntjwfm3ug8
V2EX  ›  程序员

ASP.NET Core 在路由器等 CPU 极差 内存极小的嵌入式设备上性能(并发)表现怎么样?

  •  
  •   rv54ntjwfm3ug8 · 2022-04-03 00:33:26 +08:00 · 4357 次点击
    这是一个创建于 748 天前的主题,其中的信息可能已经有所发展或是发生改变。
    38 条回复    2022-04-13 16:32:28 +08:00
    devtiange
        1
    devtiange  
       2022-04-03 08:03:57 +08:00
    根本跑不起来吧
    bthulu
        2
    bthulu  
       2022-04-03 08:15:28 +08:00
    参考 java, 本质上就是一优化过的 java
    shiganwuguo
        3
    shiganwuguo  
       2022-04-03 09:03:31 +08:00 via Android
    Asp.net 不支持 aot 也不能裁剪 hello world 就得几百兆。
    你这个需求用 go 或者 php 就好了
    jeffw
        4
    jeffw  
       2022-04-03 09:27:11 +08:00
    @shiganwuguo 我测试了一下,生成 hello world 程序,才 171KB ,并没有几百兆,vs2022+.NET6 ,默认生成的,未做任何优化裁剪。
    ![avatar]( https://s3.bmp.ovh/imgs/2022/04/03/66bdb0291accb25b.png)
    userforg2021
        5
    userforg2021  
       2022-04-03 09:31:58 +08:00
    @jeffw 他算上了 runtime ,不过几百兆夸张了,完整的 runtime 不到 100M
    antipro
        6
    antipro  
       2022-04-03 09:32:10 +08:00 via Android
    @jeffw 你没把依赖库算进去
    jeffw
        7
    jeffw  
       2022-04-03 09:47:30 +08:00
    @antipro
    确实没有算依赖库,我查找了下微软官方的文档,asp.net core 的发布是有裁剪功能的
    [关于裁剪文档]( https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained)
    我重新测试了下,采用独立发布,把 dotnet 运行时也算上,文件大小是 39.7M ,确实大不了少,不过这是在带了个运行时的情况下,感觉还可以接受。
    ![avatar]( https://s3.bmp.ovh/imgs/2022/04/03/a79df56b341bb301.png)
    yousabuk
        8
    yousabuk  
       2022-04-03 09:49:55 +08:00 via iPhone
    性能和占用内存怎么样?
    masterclock
        9
    masterclock  
       2022-04-03 10:05:07 +08:00   ❤️ 1
    39.7M 的文件可以接受的情况下,这嵌入式设备不差啊

    很多路由器 单核 500M ,16M flash ,128M ram
    ragnaroks
        10
    ragnaroks  
       2022-04-03 10:35:02 +08:00   ❤️ 1
    asp.net 我没试过,但 dotnet 本身是没问题的,有个项目 https://github.com/NiclasOlofsson/MiNET 为 dotnet 重新实现的 minecraft bedrock 服务端,编译产物 https://ci.appveyor.com/project/NiclasOlofsson/MiNET/branch/master/artifacts 解压得到 MiNET.dll 是可以在 openwrt 上(极路由 4 增强版)跑起来的,占用大概 18M 内存上下,不过我只测试了一个人的情况,而且当玩了一段时间之后,内存占用激增到 50M ,感觉还是别难为路由器了
    seakingii
        11
    seakingii  
       2022-04-03 11:42:27 +08:00   ❤️ 4
    内存极小的设备不要用带有 GC 的语言,特别是.NET 和 JAVA

    有几个问题可以说明下:

    1 独立打包出来 100K 是不可能的,那种情况应该是只编译了程序,没有带上运行时
    2 现在.net 可以"自包容"打包,就是把运行时打包上去.我自己的项目因为相对大一点,未裁剪打包出来有 100M
    3 现在.net 可以"自包容"打包成 linux 的"单文件程序",看起来像是 go 打包出来的程序一样,只是会大很多.
    4 .net 打包时可以加参数进行"裁剪","裁剪"后文件会相对更小.但是目前这个技术不是很成熟,有些引用分析不到,造成不正确的"裁剪",导致可能上线运行会出错.
    5 V2EX 前两天有个 GRPC 的性能测试报告,可以看出: .NET 写的程序性能接近甚至可能超过 RUST,但是占用的内存和 RUST 相对多一个数量级 179.23 MiB VS 18.35 MiB

    如果路由器的存储空间足够,程序逻辑不大,或许可以勉强用.NET 写的程序,但真的比较勉强.这个问题不是"性能怎么样",而是"能不能跑"...
    opengps
        12
    opengps  
       2022-04-03 12:02:49 +08:00
    很大程度上取决于优化,我的经历:
    开发了一个逻辑,刚开始时候不在乎资源利用量,提前占用资源,比如一次性取出来几万条数据,内存一下子用了上 G 规模。
    后来改成每次取一条处理,用了非常低端的机器,最高内存占用才几十兆。
    虽然修改后程序变慢了,操作也啰嗦了,但是显然可以运行在更低的设备上了。
    yaott2020
        13
    yaott2020  
       2022-04-03 12:09:02 +08:00 via Android
    建议 go 或者 c

    路由器小内存性能又不高就别折腾了
    xxfye
        14
    xxfye  
       2022-04-03 12:13:35 +08:00
    不要想,aspnet core 光几个控制器启动起来就 30M ,JIT 热起来后 100M+,复杂点项目小内存根本顶不住。
    当然,肯定比 Spring 启动就要 800M 要强很多的。
    嵌入式设备首选 C++/Rust ,宽容点就选 Go 。
    比如 Adguard Home 在我路由器( 512M )里最多也就 100M ,日志调小还能更小。
    12101111
        15
    12101111  
       2022-04-03 14:02:21 +08:00
    能用 c/c++/rust ,就不要用 go/.net ,路由器的 nor flash 那么小,放这种东西根本放不下
    pengtdyd
        16
    pengtdyd  
       2022-04-03 14:18:33 +08:00
    并发怎么样我不知道,因为在这类设备里 C 才是王者,并且是唯一的王者
    MonoLogueChi
        17
    MonoLogueChi  
       2022-04-03 14:38:27 +08:00 via Android
    .net core 性能上不差,对 cpu 要求不高,但是主要问题是对闪存和内存空间需求比较大,如果有 1G 以上的内存,500M 以上的闪存空间,是可以跑起来的,只要能跑起来,性能就不差,能接近 C++的效率。
    具体需要多大的闪存空间,要看程序本身,因为 .net core 独立打包是可以裁剪的,依赖的库越多,打包出来的程序越大。
    Ackvincent
        18
    Ackvincent  
       2022-04-03 14:40:11 +08:00
    C 更适用
    duke807
        19
    duke807  
       2022-04-03 15:08:31 +08:00 via Android
    busybox httpd 搭配 shell script 做 cgi
    INCerry
        20
    INCerry  
       2022-04-03 15:11:22 +08:00
    @shiganwuguo ASP.NET Core 支持 AOT 也支持剪裁,没有你说的那么夸张,要好几包 mb
    INCerry
        21
    INCerry  
       2022-04-03 15:21:09 +08:00
    @seakingii
    > 1. 独立打包出来 100K 是不可能的,那种情况应该是只编译了程序,没有带上运行时
    这个是可以做的,只要别依赖那些库,直接用 system call ,只是没人想这么麻烦,开心的话还能直接用 C#写 UEFI 程序
    https://github.com/MichalStrehovsky/zerosharp

    > 4. .net 打包时可以加参数进行"裁剪","裁剪"后文件会相对更小.但是目前这个技术不是很成熟,有些引用分析不到,造成不正确的"裁剪",导致可能上线运行会出错.
    这个不是 BUG ,主要是看你代码里面有没有用反射,如果用了反射这种那需要自己指定某些程序集不剪裁。

    > 5.V2EX 前两天有个 GRPC 的性能测试报告,可以看出: .NET 写的程序性能接近甚至可能超过 RUST,但是占用的内存和 RUST 相对多一个数量级 179.23 MiB VS 18.35 MiB
    .NET 是带 GC 的语言,在默认情况下,有多少内存占用多少内存,这样是性能最好的。可以自己设置堆大小和内存节省模式,grpc-bench 我用 gzh 压测 1.5wqps 大约 60m 内存。
    https://docs.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#conserve-memory
    https://docs.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector#heap-limit
    INCerry
        22
    INCerry  
       2022-04-03 15:23:51 +08:00
    @ragnaroks 可以试试配置下 gc 的 heaplimit 和 conserve-memory 参数,不过 minecraft 还是比较重的,路由器上跑这种相对来说重应用,确实比较难为它了
    INCerry
        23
    INCerry  
       2022-04-03 15:28:17 +08:00   ❤️ 1
    @opengps 我同意这位回答,内存占用和 CPU 占用主要看你的优化,和语言关系没那么大。垃圾的算法和代码,啥语言都没办法拯救。C#上用的优化方法有很多比如:使用结构体替换类、使用栈上分配、使用非托管内存、对象池化、指定内存分配到固定堆、使用 Span 和 Memroy 、计算使用 SIMD API 等等、指针和 unsafe 操作等等。
    总得来说就是人很行就不用管路平不平
    seakingii
        24
    seakingii  
       2022-04-03 19:12:55 +08:00
    @INCerry 楼主要讨论的适合不适合,而不是极限情况下能不能做.如果用.NET 什么都要都考虑各种细节,这样的用法应该是不推荐的.除非没有其它选择了.

    我没有否认某些情况下"能运行" .NET 程序 ,但目前绝对不是嵌入式设备的好的选择.
    INCerry
        25
    INCerry  
       2022-04-03 19:45:01 +08:00   ❤️ 1
    @seakingii 当然,我也没有否认你的观点,大多数是赞同的 :) 。我今天尝试了一下最新的.NET AOT ,发现 HelloWorld 和简单的 Socket 程序只要 1mb 大小,以及 2m 左右的运行空间。
    在.NET 也有针对嵌入式设备的特殊运行时如 NanoFreamwork ,可以在 STM32 之类的嵌入式设备运行,而且有很多商业案例。
    https://github.com/nanoframework/Home
    seakingii
        26
    seakingii  
       2022-04-03 19:51:21 +08:00
    @INCerry 你说的是 NativeAOT 吧?那个我也很期待,等了七八年了

    特殊运行时,感觉这些都太偏门了.以前学习用 go 做 wasm 的时候,发现有个 tinygo ,能生成更小的程序,但总有这样限制那样限制.所以我个人的观点是,如果可以选择,目前还是不要用.net 搞嵌入式的程序...除非没办法或者特别想用
    seakingii
        27
    seakingii  
       2022-04-03 19:53:46 +08:00
    @INCerry 你提到的这个 NanoFramework 有点意思,有空学习下
    beyondex
        28
    beyondex  
       2022-04-03 20:28:26 +08:00
    .NET Core 性能蛮好的,但是它官方推荐的框架(比如 ASP.NET Core )是比较重量级的,所以默认它是比较吃内存的,但是如果你的应用程序业务简单,也是可以进行简化,删掉不需要的组件,但是也需要试一下才知道。
    caotian
        29
    caotian  
       2022-04-03 21:54:01 +08:00
    mipse 和 arm 的路由器上都开发过 go 写的程序, 性能还好, go 编译完就几 M, 加上几个常用库, 包括 gin 也就 10M 出头, 还不错.
    moonheart
        30
    moonheart  
       2022-04-03 22:13:17 +08:00
    roundgis
        31
    roundgis  
       2022-04-03 23:36:49 +08:00 via Android
    @INCerry nsnoframework 已經可以商用了?
    INCerry
        32
    INCerry  
       2022-04-04 11:15:23 +08:00
    @roundgis
    是的 你加入他们的 Discord channels 看看,已经有很多人用于生产了
    roundgis
        33
    roundgis  
       2022-04-04 12:35:22 +08:00 via Android
    @INCerry 謝謝告知
    hez2010
        34
    hez2010  
       2022-04-05 12:44:11 +08:00
    试了一下,使用 asp.net core 包含完整的 runtime 进行自包含发布,然后服务端渲染出一个完整的 HTML 页面出来,编译后体积 32mb ,运行之后占用内存 34mb 。所以你这个有 128mb 内存的话我觉得还是没问题的。

    ![测试结果]( https://s1.328888.xyz/2022/04/05/LKY7y.jpg)
    hez2010
        35
    hez2010  
       2022-04-05 12:45:41 +08:00
    @hez2010 发布命令用的是 dotnet publish -c Release -r win-x64 /p:PublishTrimmed=true /p:PublishSingleFile=true
    jeeyong
        36
    jeeyong  
       2022-04-06 04:35:14 +08:00 via iPhone
    你们聊,我就吐槽一下。python 打包的自动化项目,所有依赖都装进去,到新环境直接 exe 启动的,800mb ,哈哈哈哈哈
    sjzjams
        37
    sjzjams  
       2022-04-06 08:40:26 +08:00
    前三楼说你们点啥 哈哈
    cs8425
        38
    cs8425  
       2022-04-13 16:32:28 +08:00
    来晚了
    之前工作上有稍微测试过
    linux x84_64 (i7-4710HQ)
    .net 5 vs golang 1.13.x 还 1.14.x
    跑 websocket 测带宽
    纯 http lookback 都可以跑满 CPU, 大概都有 3G+bps 左右
    https 的情况下.net 效能比 golang 好
    .net 约 500Mbps 内存约 200MB
    golang 约 300~400Mbps 内存约 80MB

    另一个测试是把 url 映射到 zip 档内的档案(碎档并发读取+解压缩, 都只用标准库)
    https 带宽上限跟上面的差不多
    但内存用量差异非常大
    golang 不最佳化的情况下 内存占用约 130MB
    .net 内存 500MB 起跳 并发越高吃越多内存
    4C 的情况下有吃超过 6GB 结果 OOM...
    基本大概抓 1C 吃 1.5 ~ 2GB 比较保守

    打包后的执行档
    golang 用 ldflags="-s -w" 约 5.6MB
    .net AOT 不带 runtime 约 4MB
    带 runtime 基本接近 100MB

    回到标题, 个人还是选 golang
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   910 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:38 · PVG 04:38 · LAX 13:38 · JFK 16:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.