如何在 JS 中快速读取文件

本文翻译自 How to read files quickly in JavaScript,作者:Daniel Lemire, 略有删改。

假设你需要在服务器上使用JavaScript读取多个文件。在像Node.js这样的运行时环境中,JavaScript有多种读取文件的方式。哪一种是最好的呢?让我们来看看各种方法的测试结果。

使用fs. promise

const fs = require('fs/promises');
const readFile = fs.readFile;
readFile("lipsum.txt", { encoding: 'utf-8' }).then((data) => {...}).catch((err) => {...})

使用fs.readFile和util.promisify

const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
readFile("lipsum.txt", { encoding: 'utf-8' })  .then((data) => {...}).catch((err) => {...})

使用fs.readFileSync

const fs = require('fs');
const readFileSync = fs.readFileSync;
var data = readFileSync("lipsum.txt", { encoding: 'utf-8' })

使用await fs.readFileSync

const fs = require('fs');
const readFileSync = fs.readFileSync;
async function f(name, options) {return readFileSync(name, options);
}

使用fs.readFile

const fs = require('fs');
const readFile = fs.readFile;
fs.readFile('lipsum.txt', function read(err, data) {...});

测试

我写了一个小型基准测试,用于反复从磁盘读取文件。这是一个简单的循环,每次都会访问相同的文件。我记录了读取文件5万次所需的毫秒数。这个文件相对较小(略超过1千字节)。我使用的是一台拥有数十个Ice Lake Intel核心和大量内存的大型服务器。我使用的Node.js版本是20.1,Bun版本是1.0.14

我多次运行了基准测试,并且在所有情况下都记录了最好的结果。你的结果可能会有所不同。

时间(Node.js)时间(Bun)
fs.promises2400 ms110 ms
fs.readFile和util.promisify1500 ms180 ms
fs.readFileSync140 ms140 ms
await fs.readFileSync220 ms180 ms
fs.readFile760 ms90 ms

至少在我的系统上,在这个测试中使用Node.js时,fs.promises比其他方式都要慢的多。在这个测试中Bun比Node.js快得多。

从某种意义上来说,fs.promises 的结果比看上去更差。我发现 readFileSync 使用了 300 毫秒的 CPU 时间,而 fs.promises 却使用了 7 秒的 CPU 时间。这是因为在进行基准测试时,fs.promises 在多个核心上触发了工作。

即使将文件大小增加到32kB,结论也并没有改变。如果你使用更大的文件,许多Node.js案例会因为“堆内存分配失败”而失败。但Bun即使处理大文件也能继续运行。测试结果并没有改变关于Bun的结论:在我的测试中,fs.readFile始终更快,即使对于大文件也是如此。


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/20672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux软件安装包rpm与tgz格式的区别

rpm与tgz的区别 1、Linux软件包的内容分类2、Linux软件包的格式分类 1、Linux软件包的内容分类 Linux应用程序的软件包按内容类别可分为两类: 可执行文件(编译后的二进制软件包) 解包后可以直接运行,看不到源代码。例如&#xff0…

基于Springboot驾校预约平台小程序的设计与实现(源码+数据库+文档)

一.项目介绍 系统角色:管理员、教练、学员 小程序(仅限于学员注册、登录): 查看管理员发布的公告信息 查看管理员发布的驾校信息 查看所有教练信息、预约(需教练审核)、评论、收藏喜欢的教练 查看管理员发布的考试信息、预约考试(需管理…

代码随想录算法训练营Day8|541. 反转字符串II、替换数字、151.翻转字符串里的单词、卡码网:55.右旋转字符串

541. 反转字符串II 1.这道题刚开始把题意理解错了,以为对于任意长度的字符串都只反转[0,k-1]以及[2k,3k-1]区间的值。 2.但实际上是要把一个字符串分成若干长度为2k的小区间,反转前[0,k-1]的字符串,[k,2k-1]保持不变; 3.如果有一个区间字符串…

2024年东北师范CCPC

文章目录 A.Paper WateringB.nIM gAMEE.Checksum A.Paper Watering 思路:题目说有平方和开方两种操作,如果这个数是平方数,那么它开方之后就只能开方,如果平方的话就重复了,反之就有开方和平方两种操作。 代码如下 //…

为了方便看公众号文章,我搭建了个博客,在线看公众号所有历史文章,想看哪天的文章一秒就能找到

公众号没有个网页版的文章列表,只能在电脑和手机客户端看,想看之前的历史文章只能一直往下拉,想找某篇文章非常费劲。 为了方便看公众号文章,我搭建了个博客,博客地址https://sushengbuhuo.github.io/blog &#xf…

通过 SFP 接口实现千兆光纤以太网通信1

基于米联客ARTIX-7 系列开发板及其开发手册。 总体实现框图如下: SFP 接口 SFP 信号定义如下图所示。 Tri Mode Ethernet MAC 设置 由于使用千兆通讯,因此将速率设为 1Gbps。如下图所示。 首先,由于该 IP 需要与 IP 核 1G/2.5G Ethernet …

基于IoTDB 平台的学习和研究

Apache IoTDB(物联网数据库)是一个针对物联网领域的高性能原生数据库,适用于数据管理和分析,并可在边缘计算和云端部署。由于它轻量级的架构、高性能和丰富的功能集,以及与Apache Hadoop、Spark和Flink的深度集成&…

【面试】生成class文件的编译器有哪些?

目录 1. 说明2. javac3. IDE(集成开发环境)中的编译器3.1 Eclipse编译器3.2 IntelliJ IDEA编译器 1. 说明 1.javac和IDE中的编译器是最常用的和主要的。2.这些编译器都能够将Java源代码编译为可在JVM上执行的字节码文件,是实现Java跨平台特性的关键。3.选择编译器时…

数据管理知识体系必知的14张语境关系图

近期对数据管理知识体系中的语境关系图进行了整体学习梳理,总共有14张图,具体如下,供大家参考。应该说语境关系图和环境因素六边形图是各有侧重、互为补充关系。语境关系图是环境因素六边形图的细化,描述了每个知识领域中的细节,相当于数据管理的微观视角, 包括与人员、 …

kali中切换python版本

kali中切换python版本 在日常使用的过程中,可以通过一些工具来做打靶环境,或者工具的启动,都和python关联,而有时存在工具安装,或者运行的时候出现报错,这时候极大可能是因为我们本地的kali中python的版本不…

Android Studio | 小白如何运行别人的安卓项目

目录 Step1:正确地打开项目 Step2:AS 同步时报错 Step3:同步完成后启动 Step4:启动成功 说明:本文简称 Android Studio 为 AS Step1:正确地打开项目 重点:确认好项目的根目录是哪个目录&am…

进程与线程(三)

进程与线程(三) 进程间通信传统间的进程间通信机制无名管道无名管道的特征无名管道的创建父子进程通信测试管道的大小管道读写易出现的问题 有名管道创建有名管道有名管道的写端代码有名管道的读端代码 信号信号的特征产生信号硬件来源软件来源发送信号的…

Linux chmod 命令

Linux chmod 命令 在 Linux 操作系统中,chmod 命令是非常重要的。它可以用于修改文件和目录的访问权限,以及控制用户对系统资源的访问。在这篇博客中,我们将深入探讨 chmod 命令的使用方法,以及如何使用它来管理文件和目录的访问…

什么是主码,什么是候选码,主码的候选码的区别是什么

目录 一、候选码 (Candidate Key) 1.定义 2.特点 二、主码 (Primary Key) 1.定义 2.特点 三、关系和区别 1.关系 2.区别 一、候选码 (Candidate Key) 1.定义 候选码是能够唯一标识数据库表中每一条记录的属性集合。一个表可以有一个或多个候选码。 2.特点 每个候选…

【U-Boot 源码深度解析】000 - 文章链接汇总

【U-Boot 源码深度解析】000 - 文章链接汇总 下载链接 https://ftp.denx.de/pub/u-boot/ 《【U-Boot 源码深度解析】001 - Ubuntu 24.04 虚拟机 及 基础环境搭建》

ORACLE RAC的一些基本理论知识

一 . Oracle RAC 的发展历程 1. Oracle Parallel Server (OPS) 早期阶段:Oracle 6 和 7 Oracle Parallel Server(OPS)是 Oracle RAC 的前身。 通过多个实例并行访问同一个数据库来提高性能。 共享磁盘架构,利用分布式锁管理&am…

JZ2440笔记:Nor FLASH驱动程序

(1)测试原有的驱动: make menuconfig修改physmap-flash驱动配置:起始0,大小0x100000,位宽2,make modules后拷贝过去测试: # insmod physmap.ko physmap platform flash device: 01000000 at 00000000 phy…

C#面:解释什么是viewstate,能否禁用?是否所用控件都可以禁用

在C#中,ViewState是 ASP.NET Web Forms中的一个重要概念。它用于在Web应用程序中跨页面请求之间保存和恢复页面的状态数据。ViewState的主要目的是在页面回发(postback)期间保持页面上的控件状态,以便在页面重新加载后能够正确地还…

addEventListener()方法中的几个参数,以及作用

addEventListener() 方法是 JavaScript 中用于处理指定元素的指定事件的函数。它有三个参数: type(必需):一个字符串,指定要监听的事件名。 listener(必需):一个实现了 EventListen…

【第1章】SpringBoot实战篇之注册接口

文章目录 前言一、代码部分1. User2.UserMapper13. UserSerivce4. UserController15. Result 二、测试1.注册2.再次注册 总结 前言 下面介绍用户注册接口。 一、代码部分 1. User package org.example.springboot3.bigevent.entity;import com.baomidou.mybatisplus.annotat…