Java、Rust、Go、NodeJS、TypeScript并发编程比较
zhezhongyun 2024-12-10 22:02 34 浏览
使用Java、Rust、Go、JavaScript (NodeJS)、TypeScript 等流行语言构建并发 Web 服务器并对其进行基准测试(Deno) 和 Kotlin 来比较这些语言/平台之间的并发性及其性能。
Rust 中的并发
高效和内存安全的并发是 Rust 的主要目标之一,这些不仅仅是简单的词,该语言为并发编程提供了强大的功能,当与同类最佳的内存安全模型相结合时,使其成为并发用例的绝佳选择。
Rust 提供构建块来创建和管理操作系统线程作为标准库的一部分,它还提供使用通道的消息传递并发(类似于 Go)和使用互斥体和智能指针的共享状态并发所需的实现。Rust 的类型系统和所有权模型有助于避免常见的并发问题,如数据竞争、锁等。
最新版本的 Rust 提供了使用async/.await语法进行异步编程所需的构建块和语言功能。但请记住,使用异步编程模型会增加整体复杂性,而且生态系统仍在不断发展。虽然 Rust 提供了所需的语言功能,但标准库不提供任何所需的实现,因此您必须使用外部 crateFutures才能有效地使用异步编程模型。
带有 Tokio 的异步多线程并发网络服务器:这是另一个使用Tokio的异步多线程网络服务器版本,由Remco Bloemen贡献。为简洁起见,我省略了导入语句。您可以在GitHub 上找到完整示例。
|
Threadpool除了异步调用之外,也有来自线程池的相同瓶颈,因此我们将线程池设置为 100 以匹配最大并发请求。
让我们使用 ApacheBench 运行一个基准测试。我们将发出 10000 个请求和 100 个并发请求。
|
Java 中的并发
这个例子更接近Rust语言的异步例子,为了简洁我省略了 import 语句。您可以在GitHub 上找到完整示例。请注意,我们在java.nio.channels.AsynchronousServerSocketChannel这里使用并且没有外部依赖项。
|
我们将异步侦听器绑定到端口 8080 并侦听所有传入请求。每个请求都在由 AsynchronousServerSocketChannel提供的新任务中处理。我们在这里没有使用任何线程池,所有传入的请求都是异步处理的,因此我们没有最大连接数的瓶颈。
让我们使用 ApacheBench 运行一个基准测试。我们将发出 10000 个请求和 100 个并发请求。
|
Go 中的并发
不要通过共享内存进行通信;相反,通过通信共享内存。Go 支持并发作为一等公民,其goroutines. Go 将协程的概念提升到一个全新的水平,使其更简单,并且成为在 Go 中执行几乎任何事情的首选方式。语义和语法非常简单,即使是 Go 新手也能从一开始就goroutines轻松上手。所有这一切都没有牺牲性能。
为简洁起见,我省略了导入语句。您可以在GitHub 上找到完整示例。在这种情况下,我们也没有使用任何外部依赖项,并且http是 Go 标准库的一部分。
|
如您所见,我们创建了一个绑定到端口 8080 的 HTTP 服务器并侦听所有传入请求。我们分配一个回调函数来处理内部调用handleConnection方法的每个请求。
让我们使用 ApacheBench 运行一个基准测试。我们将发出 10000 个请求和 100 个并发请求。
|
JavaScript 和 NodeJS 中的并发
JavaScript 是单线程的,因此实现多线程的唯一方法是启动 JS 引擎的多个实例。但是,您如何在这些实例之间进行通信?这就是Web Workers 的用武之地。
Web Workers 使在与 Web 应用程序的主执行线程分离的后台线程中运行脚本操作成为可能
在 Web Worker 的帮助下,可以将繁重的计算卸载到单独的线程,从而释放主线程。这些工作线程和主线程使用事件进行通信,一个工作线程可以产生其他工作线程。
现在,当谈到 NodeJS 时,几乎没有方法可以产生额外的线程和进程。有经典child_process模块,更现代的worker_threads模块,与 Web Worker 非常相似,以及cluster用于创建 NodeJS 实例集群的模块。
无论是 web worker 还是 worker 线程,它们都不像其他语言中的多线程实现那样灵活或简单,并且有很多限制,因此它们大多只在有 CPU 密集型任务或后台任务需要执行以供其他用途时使用使用异步处理的并发情况就足够了。
JavaScript 不提供对 OS 线程或绿色线程的访问,同样适用于 NodeJS 但是工作线程和集群很接近,因此高级多线程是不可行的。消息传递并发是可能的,由 JS 事件循环本身使用,可用于 JS 中的 Worker 和标准并发模型。在标准并发模型和使用数组缓冲区的工作线程中,共享状态并发是可能的。
我们使用cluster模块来分叉主线程和工作线程,每个 CPU 线程一个工作线程。我们仍然在http这里使用模块和回调。您可以在GitHub 上找到完整示例。在这种情况下,我们也没有使用任何外部依赖。
|
集群模块分为 master 和 worker。我们分配一个回调函数来处理内部调用该requestListener方法的每个请求。
让我们使用 ApacheBench 运行一个基准测试。我们将发出 10000 个请求和 100 个并发请求。
|
Deno 中的并发
TypeScript 中的并发性与 JavaScript 中的完全相同,因为 TypeScript 是 JavaScript 的严格超集。
因此,如果您将 TypeScript 与 NodeJS 一起使用,它与在 NodeJS 上使用 JavaScript 完全相同,因为 NodeJS 不会在本地运行 TypeScript,我们必须将其转换为 JavaScript,因此让我们专注于 Deno 上的 TypeScript,因为我们已经涵盖了 NodeJS。
与 NodeJS 不同,Deno 可以在本地运行 TypeScript,它会在幕后转换为 JS。正如我们在 NodeJS 中看到的,Deno 还专注于非阻塞 IO,旨在改进/修复 NodeJS 中的问题。这意味着你也可以在 Deno 上使用 NodeJS 和 JavaScript 完成所有可以做的事情,有时使用更好的 API 和更少的代码。就像在 JS 中一样,您依靠事件循环、回调、承诺和Async/Await来实现 TypeScript 中的并发。
Deno API 默认是异步的,并且推荐经常使用 async/await 。
Deno 中的默认并发是使用回调、Promise 或 async/await 的异步编程模型。
就像在 JavaScript 中一样,也可以在 Deno 上使用 TypeScript 进行某种程度的多线程并发和并行化,并且由于 Deno 是基于 Rust 构建的,因此未来并发性能可能会比NodeJS 上的更好。
这个例子更接近Rust 异步例子。您可以在此处在GitHub 上找到完整示例。在这种情况下,我们仅使用标准 Deno 模块。
|
我们创建了一个 HTTP 服务器并将其绑定到端口 8080 并在 for await 循环中侦听所有传入请求。每个请求都在内部使用async/await函数处理。
让我们使用 ApacheBench 运行一个基准测试。我们将发出 10000 个请求和 100 个并发请求。
|
相关推荐
- DevExpress使用教程:GridView经验小结
-
下面是笔者自己总结的使用DevExpressGridview的一些经验小结,分享给大家:1、去除GridView头上的"Dragacolumnheaderheretogroup...
- ComponentOne 新版本发布,新增 .NET 6 和 Blazor 平台控件支持
-
ComponentOneEnterprise是葡萄城推出的一款内置300多种开发控件的.NET控件集,可满足WinForm、WPF、Blazor、ASP.NETMVC等平台下的系统开发...
- Wijmo5 Flexgrid基础教程:数据绑定
-
WijmoEnterprise下载>FlexGrid在JavaScript程序中启动添加Wijmo引用;添加wijmo控件的扩展;在JavaScript中初始化wijmo控件;(可选)添加cs...
- Wijmo5 Flexgrid基础教程:InlineEdit
-
WijmoEnterprise下载>对于flexgrid,可以直接在单元格内进行编辑。但另外还有一种编辑方式,即在一行添加按钮,统一的编辑和提交数据。本文主要介绍给flexgrid添加编辑按钮...
- WinForms Data Grid控件升级(winform devexpress控件)
-
告诉大家一个好消息:慧都将于近期隆重推出“DevExpress14.2新版发布会”。心动不如行动,赶快报名吧!我们期待与您相约DevExpress14.2新版发布会。>>新增Wind...
- XAML控件宽度为另一控件的一半、静态属性绑定
-
控件上当某些数据需要根据其他数据的变化而变化很多时候,想让某个控件的宽度或者高度是另一个已有控件的一半,一开始打算使用ObjectDataProvider来实现,因为在控件上当某些数据需要根据其他数据...
- 用 CSS Grid 布局制作一个响应式柱状图
-
最新一段时间比较喜欢玩弄图表,出于好奇,我想找出比较好的用CSS制作图表的方案。开始学习网上开源图表库,它对我学习新的和不熟悉的前端技术很有帮助,比如这个:CSSGrid。今天和大家分享我学到的...
- Grid 移动端双列瀑布流(移动端瀑布流布局)
-
预览图:原理合理使用Grid的属性:display:设置为grid指明当前容器为Grid布局grid-template-columns:定义每一列的列宽(百分比或绝对单位)grid-templa...
- DevExpress导出GridControl控件数据
-
前言:使用C#做桌面应用时,我们会常常使用Winform作为我们的开发界面,但是windows自带的控件由于长时间不更新,已经不能够满足当前开发需要所以使用DevExpress控件作为Winform...
- css grid 布局的那些事儿(css grid布局和flex布局)
-
CSSGrid是一种为Web开发创建网站布局的方式。它已经存在了很多年,随着更多浏览器的支持,它终于变得越来越流行。接下来我们将了解下CSSGrid及其工作原理。了解下它如何使用。CSS...
- Grid.js - 跨框架的前端表格插件(前端table框架)
-
只想简简单单画个表格,但React,Vue,Angular,…,这么多前端框架,各自都有不同的表格渲染库。就没有表格库能“一次画表,到处运行”吗?来看看Grid.js这个跨框架的前端表格插件吧!...
- WPF开发教程01-布局控件(wpf tablecontrol控件)
-
布局控件是用于进行控件布局的容器类控件,其内部控件按照一定规律自动排列,且在父控件改变大小时,会自动适应。常用布局控件如下:1.一维布局控件(StackPanel)其内部控件按照某个维度自动排列,排...
- wxPython - 高级控件之表格Grid(wxpython grid刷新数据)
-
实战wxPython系列-043wx.grid.Grid及其相关类用于显示和编辑表格数据。它们提供了一组丰富的功能,用于显示、编辑和与各种数据源交互。wx.grid.Grid是一个功能强大的但是又稍微...
- 前端 BFC、IFC、GFC 和 FFC,这些你都知道吗?
-
如果觉得我的文章不错,可以关注我,想要看其他的进阶知识可以查看我发布过的文章!编辑搜图请点击输入图片描述BFC(Blockformattingcontexts):块级格式上下文页面上的一个隔离的...
- 20多个好用的 Vue 组件库,请查收
-
在本文中,我们将探讨一些最常见的vuejs组件。你可以收藏一波。VueTables-2地址:https://github.com/matfish2/vue-tables-2VueTables2...
- 一周热门
- 最近发表
-
- DevExpress使用教程:GridView经验小结
- ComponentOne 新版本发布,新增 .NET 6 和 Blazor 平台控件支持
- Wijmo5 Flexgrid基础教程:数据绑定
- Wijmo5 Flexgrid基础教程:InlineEdit
- WinForms Data Grid控件升级(winform devexpress控件)
- XAML控件宽度为另一控件的一半、静态属性绑定
- 用 CSS Grid 布局制作一个响应式柱状图
- Grid 移动端双列瀑布流(移动端瀑布流布局)
- DevExpress导出GridControl控件数据
- css grid 布局的那些事儿(css grid布局和flex布局)
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML常用标签 (29)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- HTML button formtarget 属性 (30)
- CSS 水平对齐 (Horizontal Align) (30)