选择后端编程语言绝非易事。毕竟不同的语言各有优缺点,我们需要考虑它是否是构建应用程序的正确工具。
Node.js 和 Python 是后端开发的两个最受欢迎的选择。两者都有非常强大的包装生态系统和社区,在两者之间进行选择可能比较困难。
在本文中,我们将分析 Node.js 和 Python 的优缺点,并分析其中一个比另一个更好的场景,以便大家可以为自己的后端做出最佳选择。
我们将涵盖以下主题:
- 什么是 Node.js?
- 什么是 Python?
- 比较架构
- 并发和并行
什么是 Node.js?
Node.js 是在 Google 的 V8 引擎上运行的异步 JavaScript 运行时。它通常用于构建实时应用程序、后端以及桌面和移动应用程序。
Node.js 是多范式的,支持以下范式:
- 事件驱动
- 至关重要的
- 面向对象
- 函数式编程
Node 由 Ryan Dahl 开发并于 2009 年发布,一炮而红,因为它首次允许 JavaScript 开发人员在 Web 浏览器之外编写 JavaScript 代码。多年来,它已经成长并成为 Python 等老语言的有力竞争者,并提供了一系列后端开发工具,如Express.js、Fastify 和 NestJS。
什么是 Python?
Python 是一种解释型通用编程语言,通常用于脚本编写、后端开发、机器学习和数据科学等。它支持多种范式,例如:
- 程序
- 面向对象
- 函数式编程
它由 Guido van Rossum 设计和开发,并于 1991 年发布并获得了主流成功;Python 一直位居TIOBE 编程社区指数的前 10 名。除此之外,谷歌、Facebook、Dropbox 和 Instagram 等大公司都将它用于内部和外部工具——甚至 NASA 也找到了它的应用程序。
Python 在不断发展,它拥有成熟的 Web 框架,例如Django、Flask和FastAPI,你也可以在后端开发项目中使用这些框架。
比较架构
软件架构描述了系统中的主要组件如何交互、关联和组织。良好的架构设计可以使系统具有可扩展性、性能良好和可维护性。
在本节中,我们将鸟瞰 Node.js 和 Python 架构。
Node.js
Node.js 是单线程、非阻塞的,并且实现了事件驱动的架构。它有一个线程,你编写的所有代码和你使用的库都在其中执行。它还利用libuv C 库提供的其他线程来处理昂贵或长时间运行的任务。
Node.js 使用回调来表示长时间运行的任务完成,一旦完成,它们会被添加到任务队列中,然后最终被添加回主线程。这种行为是 Node.js 非阻塞的原因,因为昂贵的任务不会阻塞主线程;相反,它们在单独的 libuv 线程中执行,并且 Node.js 继续执行源代码的其他部分。
Python
Python 也是一种单线程语言,主要是因为它实现了全局解释器锁 (GIL),这是一种仅允许一个线程控制 Python 解释器并在给定时间运行 Python 代码的机制。即使 Python 程序使用多个线程,GIL 也会定期在线程之间切换,让每个线程都有机会执行代码——但默认情况下它们不能并行执行。这种行为使 Python 成为单线程的。
与 Node.js 不同,Python 不是基于事件驱动的架构。但是,你仍然可以使用asyncio 包来利用它,它允许你使用 async/await 语法编写异步代码,因为它实现了事件循环、期货等。
判决
尽管语言的架构不同,但两种语言都是不错的选择,并且可以支持同步和异步编程。
并发和并行
选择后端的另一个重要方面是并发性和并行性。这些术语往往会使人们感到困惑,所以让我们定义它们,以便我们可以在同一页面上:
- 并发:两个或多个任务在多个线程中执行,但不是同时执行。相反,执行在任务之间切换,当计算机中断一个任务切换到另一个任务时,它可以从中断点继续执行另一个任务
- 并行:当多个任务同时在不同的线程中执行时
当你的应用程序任务受 CPU 限制时,并发性和并行性非常宝贵,例如在以下任务中:
- 处理图像
- 加密
- 进行复杂的计算
- 视频压缩
如果你想提高这些任务的性能,你可以将它们拆分到不同的线程中并行执行。
有了这个,现在让我们看看 Node 和 Python 如何处理并发和并行性。
Node.js
即使 Node 是单线程的,你也可以使用worker_threads模块编写多线程程序。该模块创建轻量级线程工作者,允许你并行执行 CPU 密集型 JavaScript 代码。
工作线程与主线程(父线程)共享相同的内存和进程ID,线程之间通过消息传递进行通信。你可以在博客的其他地方了解有关如何在 Node.js 中编写多线程程序的更多信息。
Python
在 Python 中,你可以使用threading 模块实现并发,该模块创建线程来执行部分代码。但是,这并不意味着线程将并行执行。这是因为 GIL,它确保只有一个线程可以执行 Python 代码,并定期在它们之间切换。
虽然并发对 I/O 密集型任务很有帮助,但 CPU 密集型任务从并行性中受益匪浅。为了实现并行性,Python 提供了多处理模块,该模块在每个内核上创建一个进程,并允许你利用多核系统并行执行 Python 代码。
每个进程都有自己的解释器和 GIL,但它确实有一些注意事项。一方面,与工作线程相比,进程的通信有限,另一方面,启动进程往往比启动线程更昂贵。
判决
Python的threading模块与Node.jsworker_thread模块相比相形见绌,后者可以轻松实现并发和并行。Node.js 之所以获胜,是因为它支持并发和并行性,而不需要像 Python 那样的变通方法。
性能和速度
更快的后端可以减少你的服务器响应时间,从而提高页面速度。良好的页面速度可以帮助你的 Web 应用程序在 Google 上获得良好的排名,并为你的用户提供良好的体验。
编程语言的速度往往与源代码的执行方式密切相关。让我们探讨一下 Node.js 和 Python 在执行期间如何比较,以及它如何影响它们各自的执行速度。
Node.js
Node 以快速执行代码而闻名,其中大部分可以归结为几个原因。
首先,如前所述,Node.js 被编译为机器码并建立在 Google V8 引擎之上,这是一个用 C++ 编写的高性能 JavaScript 引擎。V8 引擎将你的 JavaScript 编译为机器代码,因此 CPU 直接执行它,从而为你提供快速的性能。Node.js 还从 Google 对 V8 引擎的频繁性能更新中受益匪浅。
其次,Node.js 是非阻塞的,并且建立在事件驱动的架构之上。它对 Node.js 中的几乎每个 I/O 方法操作都有异步方法。由于 Node.js 是单线程的,如果一个操作耗时较长,它不会阻塞主线程。相反,它并行执行它,为代码的其他部分提供执行空间。
Python
Python 的执行速度比 Node 慢很多。有几个因素会影响 Python 的速度。对于初学者,Python 会自动将源代码编译成字节码,这是一种只有 Python 虚拟机 (PVM) 才能解释的低级格式。这会影响性能,因为 CPU 不直接执行字节码,而是由 PVM 解释代码,这会减慢执行时间。
作为该问题的解决方案,Python 有替代实现,例如PyPy,它声称通过使用即时 (JIT)比默认的 Python 实现快 4.5 倍。如果你的 Python 应用程序迫切需要速度,那么你应该考虑使用 PyPy。
话虽如此,虽然 Python 比 Node.js 慢,但它的速度对于很多项目来说仍然足够好,这就是它仍然受欢迎的原因。
判决
Node.js 是赢家,因为它的执行速度与编译成机器代码的速度一样快,而 Python 是用 PVM 解释的,这个过程往往会减慢执行速度。
可扩展性
当应用程序受到关注时,会发生以下情况:
- 由于用户数量增加,客户请求增加
- 需要处理的数据量增加
- 新功能介绍
应用程序在不损失性能的情况下因需求增加而增长和调整的能力称为扩展。
Node.js
Node.js 提供了一个原生集群模块,让你无需额外的努力即可扩展你的应用程序。该模块在多核系统中的每个核上创建一个单独的进程或工作程序。每个工作人员都有一个应用程序实例,集群模块有一个内置的负载均衡器,它使用循环算法将传入的请求分配给所有工作人员。
Node.js 也可以很好地扩展,因为它使用更少的线程来处理客户端请求。结果,它将大部分资源用于服务客户端,而不是处理可能昂贵的线程生命周期开销。
Python
Python 没有 Node.js 的集群模块的原生等价物。最接近的是多处理模块,它可以在每个核心上创建进程,但它缺少一些集群功能。做集群计算,可以使用第三方包如:
- 芹菜
- 仪表板
- 水壶
Python wiki有一个 Python 集群计算包的完整列表。
判决
与 Python 相比,Node.js 集群模块允许 Node 应用程序更容易扩展。然而,重要的是要承认现在大多数人都在使用 Docker 进行扩展。
使用 Docker,你可以创建多个容器,其中每个容器都包含一个应用程序实例。你可以创建与系统上可用的内核一样多的容器,并在每个容器中放置一个负载均衡器来分发请求。因此,无论你使用 Python 还是 Node.js,都可以使用 Docker 来简化扩展。
可扩展性
并非每种编程语言都可以有效地解决你遇到的每个问题,有时你需要使用另一种可以擅长手头任务的编程语言进行扩展。
让我们探索 Node.js 和 Python 的可扩展性。
Node.js
你可以通过使用addons使用C/C++ 扩展 Node.js。例如,C++ 插件允许你编写 C++ 程序,然后使用该require方法将其加载到你的 Node.js 程序中。借助此功能,你可以利用 C++ 库、速度或线程。
要实现插件,你可以使用:
- 节点 API
- Node.js 的本机抽象
你还可以使用 Rust 扩展 Node.js;查看本教程以了解如何操作。
Python
Python 还具有良好的语言扩展能力。你可以使用 C 或 C++ 对其进行扩展,这允许你在 Python 中调用 C/C++ 库,或者在 C/C++ 中调用 Python 代码。
你还可以使用替代 Python 实现来扩展 Python,其中包括:
- Jython:使与 Java 的集成更容易
- IronPython:允许 Python 与 Microsoft 的 .NET 框架顺利集成
判决
两者都很好地支持用其他语言扩展它们。
静态类型
Node.js 和 Python 都是动态类型语言,它们允许你快速编程,而无需为你编写的代码定义类型。但是,随着代码库的增长,需要静态类型来帮助你及早发现错误,并记录你的代码以供将来参考。尽管 Python 和 Node.js 是动态类型的,但它们都提供了静态类型工具,如果需要,你可以在代码库中使用这些工具。
Node.js
Node.js 作为 JavaScript 生态系统的一部分,拥有TypeScript,它是微软于 2012 年开发的 JavaScript 的强类型超集。TypeScript 支持渐进类型,这意味着即使没有类型,你也可以使用 TypeScript,并根据需要添加它们。
当你使用 TypeScript 时,你将源代码保存在扩展而不是扩展中,并且它涉及将所有 TypeScript 文件编译为 JavaScript 的构建步骤。由于 TypeScript 是一种独立于 Node 的语言,因此它的发展速度要快得多,并且你可以使用所有更新的功能,因为它们总是被编译为 JavaScript。.ts.js
近年来,TypeScript 越来越受欢迎,从长远来看,它在 npm 上的每周下载量超过 2900 万次。根据 Stack Overflow 2021 开发者调查,它被评为第三大最受欢迎的编程语言,超过了 Python、Node.js 和 JavaScript 本身。要了解如何使用节点设置 TypeScript,请参阅这篇文章。
Python
与 Node.js 不同,Python 不需要单独的类型语言。相反,它带有可以在项目中使用的类型提示。但是,Python 不会自行执行静态类型分析;相反,你使用mypy 之类的工具进行静态类型检查。如果你想了解如何在 Python 中进行静态类型检查,请参阅这篇文章。
Python 的类型提示方法的优点是你不必为源代码使用不同的文件扩展名并将其编译为 Python 文件扩展名。但缺点是每个新的 Python 版本都会引入更新的类型提示,每个版本大约需要一年时间。另一方面,TypeScript 的发布时间表为 3-4 个月。
判决
Node.js 之所以获胜,是因为 TypeScript 的发展速度比 Python 快得多。但是,承认 Python 无需其他语言即可添加类型的能力也很好。
社区和图书馆
社区在软件开发中扮演着重要角色。具有大型社区的编程语言往往具有:
- 更多用于开发的库和工具
- 更多学习内容
- 更容易找到支持
- 更容易找到出租的开发商
Node.js 和 Python 同样拥有强大的社区,但让我们仔细看看它们中的每一个。
Node.js
Node.js 拥有一个强大而活跃的社区,该社区已经构建了超过一百万个开源包,所有这些都可以在 npm 上提供给你。
以下是你可能会遇到的一些软件包:
- Express:用于构建 Web 应用程序的 Web 框架
- Axios : 用于发出 API 请求
- Lodash:一个实用程序库
要发现更多包,可以参阅 GitHub 上精选的 awesome-nodejs 存储库。
除了软件包,Node.js 有大量高质量的书面内容,视频教程分布在许多平台上,包括这个博客。这使得学习 Node.js 变得更加容易,当你被困在一个任务上时,更有可能有人在你之前在 Stack Overflow 等问答平台上问过这个问题。
此外,Node.js 还有很多国际会议,你可以在其中了解更多关于 Node.js 并结识其他人,以及专注于 Node.js 的在线社区。
Python
Python 还拥有一个活跃的社区,在Python 包索引上拥有超过 37 万个包和 340 万个版本。你可以使用pip将它们下载到你的项目中,这是一个从 Python 包索引中提取包的包安装程序。
以下是一些流行的软件包:
- NumPy:一个处理数组的库
- Pandas:用于分析数据
- Django:一个网络框架
有关完整列表,请参阅awesome-python GitHub 存储库。
与 Node.js 一样,Python 拥有大量视频和书面内容,以及活跃的在线社区,以及在 40 多个国家/地区举行的Python 会议 (PyCon)等会议。
判决
他们都在这里获胜,因为 Node 和 Python 都拥有高质量的内容、活跃的社区以及大量用于开发的包。
常见用例
Python 和 Node.js 各有优缺点,我们在此进行了深入介绍。由于 Python 的包和社区,一些任务更适合 Python,而由于语言的体系结构和其他因素,一些任务更适合 Node.js。
Node.js
由于 Node.js 的非阻塞和事件驱动架构,它往往常用于:
- CPU 绑定操作:由于良好的多线程支持
- I/O 操作:由于非阻塞和事件驱动的架构
- 实时应用程序:使用像socket.io 这样的库
Python
另一方面,科学界大力支持 Python,因此有许多用于机器学习、数据分析等的软件包,例如:
- 数字货币
- 科学派
- Matplotlib
如果你的应用程序更专注于数据分析或使用科学家使用的工具,那么 Python 是一个很好的选择。
判决
两者都很好。这主要取决于你想用它们做什么。Node.js 适用于实时应用程序,而 Python 适用于需要数据分析和可视化的应用程序。
结论
我们已经到了本文的结尾。我们已经了解了 Python 和 Node.js 之间的区别,我希望你已经了解到没有完美的工具。尽管如此,这些语言仍在努力解决其局限性,无论是使用内置工具还是第三方工具。
你对后端语言的选择很大程度上取决于你要构建的应用程序类型,我希望本指南可以帮助你为后端做出正确的决定。
仅200个监控生产中失败和缓慢的网络请求
部署基于节点的 Web 应用程序或网站是很容易的部分。确保你的 Node 实例继续为你的应用程序提供资源是事情变得更加困难的地方。如果你有兴趣确保对后端或第三方服务的请求成功可以尝试 LogRocket。
https://logrocket.com/signup/
LogRocket就像一个用于网络和移动应用程序的 DVR,记录用户与你的应用程序交互时发生的所有事情。无需猜测问题发生的原因,你可以汇总和报告有问题的网络请求,以快速了解根本原因。
LogRocket 检测你的应用程序以记录基准性能时间,例如页面加载时间、第一个字节的时间、缓慢的网络请求,并记录 Redux、NgRx 和 Vuex 操作/状态。免费开始监控。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/8521.html