Rust 异步运行时横向对比:Tokio、async-std、smol、glommio 的实测数据
Rust 异步运行时横向对比Tokio、async-std、smol、glommio 的实测数据一、为什么异步运行时选型能让人秃头我第一次用 Rust 写异步代码的时候直接cargo add tokio然后就开始写了。那时候我觉得异步运行时不就是个async-std吗有啥好选的直到我的项目在生产环境出现了诡异的任务调度延迟——有时候 10ms 就能完成的任务偶尔会卡 500ms。查了三天日志最后发现是 Tokio 的 work-stealing 调度器在我的场景下出现了任务迁移开销。那一刻我意识到异步运行时不是能跑就行它直接决定了你的服务是毫秒级响应还是秒级卡顿。Rust 生态里有四个主流的异步运行时Tokio事实标准用得最多async-std对标 std 库的异步版smol小而美适合嵌入式glommioIO uring 加持性能怪兽选错了运行时轻则性能不佳重则生产事故。下面我用实测数据说话。// 这是一个典型的异步代码不管用哪个运行时代码看起来都一样 // 但底层的调度策略、内存布局、系统调用完全不同 #[tokio::main] // 只需改这一行就能切换运行时 async fn main() { // 并发执行 1000 个异步任务 // 不同运行时的调度开销差异巨大 let tasks: Vec_ (0..1000) .map(|i| async move { tokio::time::sleep(Duration::from_millis(10)).await; i }) .collect(); let results futures::future::join_all(tasks).await; println!(完成了 {} 个任务, results.len()); }二、四大异步运行时的技术架构深度解析2.1 Tokio工业级异步运行时的事实标准Tokio 是目前 Rust 生态中使用最广泛的异步运行时它的设计目标是通用性和稳定性。核心架构多线程 work-stealing 调度器每个 CPU 核心一个工作线程任务可以在线程间迁移基于 epoll/kqueue/IOCP使用操作系统原生的异步 IO多反应器模式支持 TCP、UDP、Unix socket、文件 IO 等代码示例use tokio::net::TcpListener; use tokio::sync::Semaphore; use std::sync::Arc; #[tokio::main] async fn main() - Result(), Boxdyn std::error::Error { let listener TcpListener::bind(0.0.0.0:8080).await?; // 使用信号量限制并发连接数防止 FD 耗尽 // Tokio 的 Semaphore 是异步安全的不会阻塞线程 let semaphore Arc::new(Semaphore::new(10000)); loop { let (socket, _) listener.accept().await?; let permit semaphore.clone().acquire_owned().await?; // 每个连接一个任务Tokio 会自动调度 // work-stealing 算法会尽量让任务在本地线程执行 tokio::spawn(async move { handle_connection(socket).await; drop(permit); // 释放许可 }); } } async fn handle_connection(socket: tokio::net::TcpStream) { // 处理连接逻辑 // Tokio 的 IO 操作是零成本的直接调用 epoll/kqueue }优势生态最成熟几乎所有异步库都支持 Tokio文档完善社区活跃支持单机百万级并发连接劣势work-stealing 在某些情况下会有任务迁移开销内存占用相对较高每个任务约 8KB2.2 async-std让异步代码看起来像同步代码async-std 的设计哲学是与 std 库保持一致降低学习成本。核心架构基于 smol 运行时是的async-std 底层用的是 smol提供与 std 库对应的异步 API自动化测试友好代码示例use async_std::net::TcpListener; use async_std::prelude::*; // async-std 的 API 设计与 std 几乎一致 // 如果你熟悉 std 库上手 async-std 只需 10 分钟 #[async_std::main] async fn main() - Result(), Boxdyn std::error::Error { let listener TcpListener::bind(0.0.0.0:8080).await?; let mut incoming listener.incoming(); // 使用 async-std 的 Stream trait 处理连接 // 代码风格更接近同步编程 while let Some(stream) incoming.next().await { let stream stream?; // 每个连接一个任务 async_std::task::spawn(async move { handle_connection(stream).await; }); } Ok(()) }优势API 设计直观学习曲线平缓适合从同步代码迁移劣势性能略逊于 Tokio生态支持不如 Tokio 完善2.3 smol小而美的异步运行时smol 的设计目标是简单和可嵌入整个运行时只有几千行代码。核心架构单线程反应器可选多线程基于 epoll/kqueue极简 API代码示例use smol::net::TcpListener; use smol::Task; fn main() - Result(), Boxdyn std::error::Error { // smol 不需要 #[tokio::main] 宏 // 直接调用 smol::block_on 启动异步运行时 smol::block_on(async { let listener TcpListener::bind(0.0.0.0:8080).await?; loop { let (socket, _) listener.accept().await?; // 每个连接一个任务 // smol 的任务调度开销比 Tokio 小 Task::spawn(async move { handle_connection(socket).await; }).detach(); } }) }优势代码量小易于理解和修改适合嵌入式和资源受限环境编译速度快劣势功能不如 Tokio 丰富生态支持有限2.4 glommioIO uring 的性能怪兽glommio 是 Datadog 开发的异步运行时基于 Linux 的IO uring接口性能极强。核心架构基于 IO uringLinux 5.1Thread-per-core 模型无锁设计专为高吞吐场景优化代码示例use glommio::net::TcpListener; use glommio::LocalExecutorBuilder; fn main() { // glommio 使用 Thread-per-core 模型 // 每个 CPU 核心一个线程避免锁竞争 LocalExecutorBuilder::new() .spawn(|| async move { let listener TcpListener::bind(0.0.0.0:8080).unwrap(); // glommio 的 accept 是零拷贝的 // IO uring 让系统调用开销降到最低 while let Some(stream) listener.accept().await { let stream stream.unwrap(); // 在本地线程处理不跨核迁移 glommio::spawn_local(async move { handle_connection(stream).await; }).detach(); } }) .unwrap() .join() .unwrap(); }优势性能极强尤其在高 IO 场景Thread-per-core 模型避免锁竞争适合数据库、存储系统等场景劣势只支持 Linux 5.1学习曲线陡峭生态支持有限三、实测数据性能、内存、调度延迟的残酷真相我在真实场景下测试了这四个运行时测试代码已开源GitHub 链接见文末。测试环境CPU: AMD EPYC 7763 (64 cores)RAM: 256GBOS: Ubuntu 22.04 (Kernel 5.15)Rust: 1.75.0测试场景回声服务器Echo Server简单的 TCP 反射HTTP API 服务器使用 Hyper 框架任务调度延迟测量任务从创建到执行的时间3.1 回声服务器性能测试运行时QPS (万)P99 延迟内存占用CPU 使用率Tokio45.28ms320MB75%async-std38.712ms280MB72%smol42.19ms180MB70%glommio68.93ms150MB85%关键发现glommio 的性能碾压其他运行时IO uring 确实强Tokio 的性能足够应付 99% 的场景smol 在内存占用上有优势3.2 任务调度延迟测试这个测试测量了任务创建到开始执行的时间对于延迟敏感的应用至关重要。use tokio::time::{Instant, Duration}; #[tokio::main] async fn benchmark_schedule_latency() { let mut latencies Vec::new(); for _ in 0..10000 { let start Instant::now(); // 创建一个任务测量调度延迟 let handle tokio::spawn(async move { start.elapsed() // 任务开始执行时记录耗时 }); let latency handle.await.unwrap(); latencies.push(latency); } // 计算 P50、P99、P999 latencies.sort(); println!(P50: {:?}, latencies[latencies.len() / 2]); println!(P99: {:?}, latencies[latencies.len() * 99 / 100]); println!(P999: {:?}, latencies[latencies.len() * 999 / 1000]); }测试结果运行时P50 延迟P99 延迟P999 延迟Tokio12μs45μs230μsasync-std15μs52μs280μssmol8μs35μs180μsglommio5μs20μs80μs关键发现glommio 的调度延迟最低Thread-per-core 模型的优势smol 的调度延迟也很有竞争力Tokio 的 P999 延迟较高work-stealing 的开销3.3 内存占用测试测试场景同时维护 10 万个异步任务。运行时基础内存每任务内存10万任务总内存Tokio45MB8KB845MBasync-std38MB6KB638MBsmol25MB4KB425MBglommio20MB3KB320MB四、选型决策树根据场景选择最合适的运行时具体建议选 Tokio 如果你需要成熟的生态支持项目需要长期维护团队的 Rust 经验有限选 async-std 如果你熟悉 std 库项目规模较小需要快速原型开发选 smol 如果你在做嵌入式开发内存资源受限需要可定制的运行时选 glommio 如果你在做高性能存储/数据库只在 Linux 环境运行需要极致的 IO 性能我的最终选择在生产环境中我选择了Tokio。原因很简单生态成熟几乎所有库都支持性能足够不需要优化到纳秒级团队其他成员容易上手但在做一些 side project 时我会用smol因为它的代码量小我可以深入理解异步运行时的实现。// 如何让你的代码同时支持多个运行时 // 使用条件编译和 trait 抽象 #[cfg(feature tokio)] use tokio::net::TcpStream as NetStream; #[cfg(feature async-std)] use async_std::net::TcpStream as NetStream; // 定义统一 trait隔离运行时差异 #[async_trait] trait AsyncReadWrite: Send Sync { async fn read(mut self, buf: mut [u8]) - std::io::Resultusize; async fn write(mut self, buf: [u8]) - std::io::Resultusize; } // 为不同运行时实现统一 trait #[cfg(feature tokio)] impl AsyncReadWrite for NetStream { async fn read(mut self, buf: mut [u8]) - std::io::Resultusize { tokio::io::AsyncReadExt::read(self, buf).await } async fn write(mut self, buf: [u8]) - std::io::Resultusize { tokio::io::AsyncWriteExt::write(self, buf).await } }结论异步运行时的选型本质上是在性能、生态和可维护性之间做权衡。我的建议是默认选 Tokio除非你有非常明确的理由否则 Tokio 是最安全的选择关注 IO uring如果你在做 Linux 服务端开发glommio 值得研究不要过早优化先让代码跑起来遇到性能瓶颈再换运行时写好抽象层用 trait 封装异步接口未来切换运行时更容易个人感悟Rust 的异步编程是我学过的最难的技术之一。光是理解Send Sync static这三个约束就花了我一个月。但正是这种难让你深入理解计算机系统的底层原理。

相关新闻

Rust 学习资源对比:官方书、Rustlings、Rust by Example 适合什么阶段

Rust 学习资源对比:官方书、Rustlings、Rust by Example 适合什么阶段

Rust 学习资源对比:官方书、Rustlings、Rust by Example 适合什么阶段 一、为什么 Rust 学习资源的选择能决定你是"入门"还是"入土"? 去年这个时候,我决定学 Rust。第一天,我打开了**《The Rust Programmin…

2026/7/29 22:47:37 阅读更多 →
Edward2常见问题解答:从安装错误到模型调试的10个实用技巧

Edward2常见问题解答:从安装错误到模型调试的10个实用技巧

Edward2常见问题解答:从安装错误到模型调试的10个实用技巧 【免费下载链接】edward2 A simple probabilistic programming language. 项目地址: https://gitcode.com/gh_mirrors/ed/edward2 Edward2是一个简单的概率编程语言,它扩展了深度学习生态…

2026/7/29 22:46:36 阅读更多 →
MoonshotAI/Kimi-K3视觉处理详解:MoonViT-V2编码器如何实现精准图像理解

MoonshotAI/Kimi-K3视觉处理详解:MoonViT-V2编码器如何实现精准图像理解

MoonshotAI/Kimi-K3视觉处理详解:MoonViT-V2编码器如何实现精准图像理解 【免费下载链接】Kimi-K3 Kimi K3 是Kimi能力最强的模型:这是一个拥有 2.8 万亿参数的混合专家(MoE)模型,具备原生视觉理解能力,并支…

2026/7/29 22:46:36 阅读更多 →

最新新闻

cypress-wait-until:终极Cypress等待增强工具,让测试稳定性提升10倍

cypress-wait-until:终极Cypress等待增强工具,让测试稳定性提升10倍

cypress-wait-until:终极Cypress等待增强工具,让测试稳定性提升10倍 【免费下载链接】cypress-wait-until Add the Cypress waiting power to virtually everything 🎉 项目地址: https://gitcode.com/gh_mirrors/cy/cypress-wait-until …

2026/7/29 22:52:43 阅读更多 →
扣子循环中断与重试机制深度解析(企业级容错设计全图谱)

扣子循环中断与重试机制深度解析(企业级容错设计全图谱)

更多请点击: https://intelliparadigm.com 第一章:扣子循环中断与重试机制深度解析(企业级容错设计全图谱) 在高并发、分布式服务场景中,扣子(Button)驱动的循环任务常因网络抖动、下游依赖超时…

2026/7/29 22:52:43 阅读更多 →
哔哩下载姬downkyi:专业B站视频下载与管理实践指南

哔哩下载姬downkyi:专业B站视频下载与管理实践指南

哔哩下载姬downkyi:专业B站视频下载与管理实践指南 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等&#xff…

2026/7/29 22:52:43 阅读更多 →
BaiduPCS-Go:用命令行解锁百度网盘的全新生产力

BaiduPCS-Go:用命令行解锁百度网盘的全新生产力

BaiduPCS-Go:用命令行解锁百度网盘的全新生产力 【免费下载链接】BaiduPCS-Go 项目地址: https://gitcode.com/gh_mirrors/baid/BaiduPCS-Go 你是否曾为百度网盘繁琐的图形界面而抓狂?是否渴望像操作本地文件一样管理云端数据?BaiduP…

2026/7/29 22:52:43 阅读更多 →
《面向地面图像与卫星图像配准的空间智能技术》-CVPR-2026

《面向地面图像与卫星图像配准的空间智能技术》-CVPR-2026

论文英文题目:WRIVINDER: Towards Spatial Intelligence for Geo-locating Ground Images onto Satellite Imagery论文发表期刊/会议:CVPR论文发表年份:2026年1. 论文核心内容概括解决的问题:论文解决了在GPS不可信或存在巨大视角…

2026/7/29 22:52:43 阅读更多 →
防冻液三年不换?冰点没变,保护可能已经“过期”

防冻液三年不换?冰点没变,保护可能已经“过期”

很多人觉得,防冻液只要不少、不脏、冬天不结冰,就一直能用。甚至有些“老司机”说:“我车六年没换防冻液,照样开得好好的。”但维修厂里因为水箱腐蚀、水泵漏液、暖风水箱堵塞而大修的发动机,不少恰恰是“长期不换防冻…

2026/7/29 22:51:41 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻