深入讨论JavaScript中Set对象如何让代码更快

2023-05-16

我确信有很多开发人员坚持使用基本的全局对象:数字,字符串,对象,数组和布尔值。对于许多用例,这些都是需要的。 但是如果想让你的代码尽可能快速和可扩展,那么这些基本类型并不总是足够好。

在本文中,我们将讨论JS 中Set对象如何让代码更快— 特别扩展性方便。 Array 和Set工作方式存在大量的交叉。但是使用Set会比Array在代码运行速度更有优势。

Set 有何不同

最根本的区别是数组是一个索引集合,这说明数组中的数据值按索引排序。


const arr = [A, B, C, D];
console.log(arr.indexOf(A)); // Result: 0
console.log(arr.indexOf(C)); // Result: 2
  

相比之下,set是一个键的集合。set不使用索引,而是使用键对数据排序。set 中的元素按插入顺序是可迭代的,它不能包含任何重复的数据。换句话说,set中的每一项都必须是惟一的。

主要的好处是什么

set 相对于数组有几个优势,特别是在运行时间方面:

  • 查看元素:使用indexOf()includes()检查数组中的项是否存在是比较慢的。
  • 删除元素:在Set中,可以根据每项的的 value 来删除该项。在数组中,等价的方法是使用基于元素的索引的splice()。与前一点一样,依赖于索引的速度很慢。
  • 保存 NaN:不能使用indexOf()或 includes() 来查找值 NaN,而 Set 可以保存此值。
  • 删除重复项Set对象只存储惟一的值,如果不想有重复项存在,相对于数组的一个显著优势,因为数组需要额外的代码来处理重复。

时间复杂度?

数组用来搜索元素的方法时间复杂度为0(N)。换句话说,运行时间的增长速度与数据大小的增长速度相同。

相比之下,Set用于搜索、删除和插入元素的方法的时间复杂度都只有O(1),这意味着数据的大小实际上与这些方法的运行时间无关。

Set 究竟有多快?

虽然运行时间可能会有很大差异,具体取决于所使用的系统,所提供数据的大小以及其他变量,但我希望我的测试结果能够让你真实地了解Set的速度。 我将分享三个简单的测试和我得到的结果。

准备测试

在运行任何测试之前,创建一个数组和一个 Set,每个数组和 Set 都有100万个元素。为了简单起见,我从0开始,一直数到999999

let arr = [], set = new Set(), n = 1000000;
for (let i = 0; i < n; i++) {
  arr.push(i);
  set.add(i);
}

测试1:查找元素

我们搜索数字123123

let result;
console.time('Array'); 
result = arr.indexOf(123123) !== -1; 
console.timeEnd('Array');
console.time('Set'); 
result = set.has(123123); 
console.timeEnd('Set');
  • Array: 0.173ms
  • Set: 0.023ms

Set 速度快了7.54

测试2:添加元素

console.time('Array'); 
arr.push(n);
console.timeEnd('Array');
console.time('Set'); 
set.add(n);
console.timeEnd('Set');
  • Array: 0.018ms
  • Set: 0.003ms

Set 速度快了6.73

测试3:删除元素

最后,删除一个元素,由于数组没有内置方法,首先先创建一个辅助函数:

const deleteFromArr = (arr, item) => {
  let index = arr.indexOf(item);
  return index !== -1 && arr.splice(index, 1);
};

这是测试的代码:

console.time('Array'); 
deleteFromArr(arr, n);
console.timeEnd('Array');
console.time('Set'); 
set.delete(n);
console.timeEnd('Set');
  • Array: 1.122ms
  • Set: 0.015ms

Set 速度快了74.13

总的来说,我们可以看到,使用Set 极大地改善运行时间。再来看看一些Set有用的实际例子。

案例1:从数组中删除重复的值

如果想快速地从数组中删除重复的值,可以将其转换为一个 Set。这是迄今为止过滤惟一值最简洁的方法:

const duplicateCollection = ['A', 'B', 'B', 'C', 'D', 'B', 'C'];
// 将数组转换为 Set
let uniqueCollection = new Set(duplicateCollection);
console.log(uniqueCollection) // Result: Set(4) {"A", "B", "C", "D"}
// 值保存在数组中
let uniqueCollection = [...new Set(duplicateCollection)];
console.log(uniqueCollection) // Result: ["A", "B", "C", "D"]

案例2:谷歌面试问题

问题:

给定一个整数无序数组和变量 sum,如果存在数组中任意两项和使等于 sum 的值,则返回true。否则,返回false。例如,数组[3,5,1,4]和 sum = 9,函数应该返回true,因为4 + 5 = 9

解答

解决这个问题的一个很好的方法是遍历数组,创建 Set保存相对差值。

当我们遇到3时,我们可以把6加到Set中, 因为我们知道我们需要找到9的和。然后,每当我们接触到数组中的新值时,我们可以检查它是否在 Set 中。当遇到5时,在 Set 加上4。最后,当我们最终遇到4时,可以在Set中找到它,就返回true

const findSum = (arr, val) => {
  let searchValues = new Set();
  searchValues.add(val - arr[0]);
  for (let i = 1, length = arr.length; i < length; i++) {
    let searchVal = val - arr[i];
    if (searchValues.has(arr[i])) {
      return true;
    } else {
      searchValues.add(searchVal);
    }
  };
  return false;
};

简洁的版本:

const findSum = (arr, sum) =>
  arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));

因为Set.prototype.has()的时间复杂度仅为O(1),所以使用 Set 来代替数组,最终使整个解决方案的线性运行时为O(N)

如果使用 Array.prototype.indexOf()Array.prototype.includes(),它们的时间复杂度都为 O(N),则总运行时间将为O(N²),慢得多!

原文地址:https://medium.com/@bretcameron/how-to-make-your-code-faster-using-javascript-sets-b432457a4a77

为了保证的可读性,本文采用意译而非直译。

更多编程相关知识,请访问:编程学习网站!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入讨论JavaScript中Set对象如何让代码更快 的相关文章

  • 扩展Vue.js组件

    您的Vue应用程序中是否有共享类似选项的组件 xff0c 甚至模板标记 使用公共选项和标记创建基本组件 xff0c 然后扩展基本组件以创建子组件 xff0c 这是一个好主意 这样的体系结构将帮助您在代码中应用DRY原则 不要重复您自己 xf
  • Node.js日志记录指南

    当你开始用 JavaScript 进行开发时 xff0c 可能学到的第一件事就是如何用 console log 将内容记录到控制台 如果你去搜索如何调试 JavaScript xff0c 会发现数百篇博文和 StackOverflow 文章
  • 软件测试的测试方法及测试流程

    一 测试方法 xff1a 白盒测试 xff1a 把软件比作一个打开的盒子 xff0c 可以看到软件代码的实现 xff0c 针对代码的实现验证代码是否存在问题 单元测试阶段采用的测试方法 灰盒测试 xff1a 介于白盒和黑盒测试之间 灰盒测试
  • 18个用于创建漂亮图表的JavaScript库推荐

    几乎不可能想象没有图形和图表的任何仪表盘 它们快速有效地呈现复杂的统计数据 此外 xff0c 一个好的图表还可以增强网站的整体设计 在本文中 xff0c 我将向您展示一些用于图形和图表的最佳JavaScript库 这些库将帮助您为将来的项目
  • JavaScript基础--引用数据类型 (对象)

    本文主要讲述了JavaScript对象的属性和对象的引用 xff0c 以及对象的读取 赋值 删除和获取对象键名的操作 1 对象 对象就是一组 键值对 xff08 key value xff09 的集合 xff0c 是一种无序的复合数据集合
  • javascript面向对象设计

    javascript和java语言不一样 xff0c 它没有类这个说法 xff0c 更没有子类父类一说 xff0c 所以它所谓的继承机制 xff0c 也是和其他语言完全不同的 创建对象三种方式 1 最简单的方式 xff0c 创建一个obje
  • 关键CSS和Webpack:自动最小化渲染阻止CSS

    消除渲染阻止的JavaScript和CSS 这是我始终坚持使用的Google Page Speed Insights建议 Google建议您在页面加载准备就绪时将最初需要的CSS 内插 CSS内嵌并加载CSS的其余部分 当访问web页面时
  • 如何用SASS编写可重用的CSS

    Sass是一个CSS预处理程序 xff0c 它在前端工程师的工具箱中变得至关重要 Sass之所以流行 xff0c 是因为它修复了几个CSS缺陷 相关推荐 xff1a css在线手册 这也是Bootstrap 4运行的基础 这意味着为了理解如
  • JS 变量的作用域及闭包

    与闭包有关的概念 xff1a 变量的作用域和变量的生存周期 下面本篇文章就来给大家介绍一下JS中变量的作用域及闭包 xff0c 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c 希望对大家有所帮助 一 变量的作用域 1 变
  • 理解JavaScript中的变量、范围和提升

    变量是许多编程语言的基本组成部分 xff0c 也是新手需要学习的第一个也是最重要的概念 JavaScript中有许多不同的变量属性 xff0c 以及命名变量时必须遵循的一些规则 在JavaScript中 xff0c 有三个关键字用于声明变量
  • 用于VueJS和Webpack的代码分割模式

    拆分单个页面应用程序的代码是提高其初始加载速度的一个很好的方法 由于用户不必一次性下载所有代码 xff0c 他们将能够更快地看到页面并与页面进行交互 这将提高用户体验 xff0c 特别是在移动领域 xff0c 这是搜索引擎优化的一个胜利 x
  • javascript掌握正则表达式

    正则表达式 xff08 英语 xff1a Regular Expression xff0c 在代码中常简写为regex regexp或RE xff09 使用单个字符串来描述 匹配一系列符合某个句法规则的字符串搜索模式 我想正则表达式之所以难
  • 知道要测试什么——Vue组件单元测试

    关于单元测试Vue组件 xff0c 我看到的最常见的问题是 我到底应该测试什么 虽然测试过多或过少都是可能的 xff0c 但我的观察是 xff0c 开发人员通常会在测试过多时犯错误 毕竟 xff0c 没有人愿意成为一个组件测试不足导致应用程
  • 软件测试 | 测试开发书单 | 测试工程师必读经典好书,你读过几本?

    测试好书1080 480 46 3 KB 软件测试入行容易进阶难 在持续交付体系背景下 xff0c 要成为测试开发高手意味着非常系统综合的知识储备 广泛阅读经典好书是快速成长的必要方式 霍格沃兹测试学院重点推荐几本测试经典好书以及必读清单
  • 使用webpack提升vue.js应用程序的四种方法

    Webpack是开发Vue js单页面应用程序的必要工具 通过管理复杂的构建步骤 xff0c 它使您的开发工作流更加简单 xff0c 并且可以优化应用程序的大小和性能 在本文中 xff0c 我将解释Webpack提升Vue应用程序的四种方法
  • 了解Node.js中的流(Stream)

    Node js 中的流 xff08 Stream xff09 是出了名的难用甚至是难以理解 用 Dominic Tarr 的话来说 xff1a 流是 Node 中最好的 xff0c 也是最容易被误解的想法 即使是 Redux 的创建者和 R
  • 深入了解Vue.js的作用域插槽

    作用域槽是Vue js的一个有用特性 xff0c 它可以使组件更加通用和可重用 唯一的问题是它们很难理解 试着让你的头在父母和孩子的范围内交织 xff0c 就像解决一个棘手的数学方程 当你不能很容易地理解某件事时 xff0c 一个好的方法是
  • JavaScript常用基础算法

    一个算法只是一个把确定的数据结构的输入转化为一个确定的数据结构的输出的function 算法内在的逻辑决定了如何转换 基础算法 一 排序 1 冒泡排序 冒泡排序function bubbleSort arr for var i 61 1 l
  • HTML中的meta标签属性的使用

    之前学习前端中 xff0c 对meta标签的了解仅仅只是这一句 lt meta charset 61 34 UTF 8 34 gt 但是打开任意的网站 xff0c 其head标签内都有一列的meta标签 下面我们就来详细介绍一下meta标签
  • 移动端H5开发常用小技巧(总结)

    本篇文章给大家整理一些在移动端H5开发常见的问题给大家做下分享 xff0c 这里很多是在开发过程中遇到的大坑或者遭到过吐糟的问题 xff0c 希望能给大家带来或多或少的帮助 html 篇 常用的meta属性设置 meta对于移动端的一些特殊

随机推荐

  • JavaScript中Switch语句的使用方法

    除了if else之外 xff0c JavaScript还有一个称为switch语句的功能 switch是一种条件语句 xff0c 它将针对多种可能的情况评估表达式 xff0c 并根据匹配的情况执行一个或多个代码块 switch语句与包含许
  • 如何构建可运行的JavaScript规范

    编程不仅仅是给计算机下达如何完成一项任务的指令 xff0c 它还包括以一种精确的方式与他人交流思想 xff0c 甚至是与未来的自己 这样的交流可以有多个目标 xff0c 也许是为了共享信息 xff0c 或者只是为了更容易地修改 如果你不理解
  • javascript中函数的5个高级技巧

    函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块 函数对任何一门语言来说都是一个核心的概念 xff0c 在javascript中更是如此 本文将深入介绍函数的5个高级技巧 作用域安全的构造函数 构造函数其实就是一个使用new操作符
  • 理解JavaScript中的原型和继承

    本文主要讲了原型如何在JavaScript中工作 xff0c 以及如何通过 Prototype 所有对象共享的隐藏属性链接对象属性和方法 xff1b 以及如何创建自定义构造函数以及原型继承如何工作以传递属性和方法值 介绍 JavaScrip
  • 大学毕业后转行软件测试我后悔了

    来自一篇新学员的留言 大学本科幼师专业 xff0c 家里人都想让我考教师资格证 xff0c 等毕业了当一名人民教师 xff0c 说这个职业是一辈子的铁饭碗 xff0c 风吹不着雨淋不到 xff0c 还有寒暑假 xff0c 找个离家近的 xf
  • 分享5个JS函数的高级技巧

    函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块 函数对任何一门语言来说都是一个核心的概念 xff0c 在javascript中更是如此 本文将深入介绍函数的5个高级技巧 作用域安全的构造函数 构造函数其实就是一个使用new操作符
  • 详解vue.js中watch的使用

    在vue中 xff0c 使用watch来响应数据的变化 watch的用法大致有三种 下面代码是watch的一种简单的用法 xff1a lt input type 61 34 text 34 v model 61 34 cityName 34
  • Vue中值得关注的21个开源项目(推荐)

    Vue 相对不于 React 的一个优点是它易于理解和学习 xff0c 且在国内占大多数 咱们可以在 Vue 的帮助下创建任何 Web 应用程序 因此 xff0c 时时了解一些新出现又好用的Vue 开源项目也是挺重要 xff0c 一方面可以
  • javaScript面向对象的三个基本特征介绍

    了解过面向对象的同学应该都知道 xff0c 面向对象三个基本特征是 xff1a 封装 继承 多态 xff0c 但是对于这三个词具体可能不太了解 对于前端来讲接触最多的可能就是封装与继承 xff0c 对于多态来说可能就不是那么了解了 封装 在
  • 7个实用的CSS background-image小技巧

    xff08 推荐教程 xff1a CSS教程 xff09 background image可能是我们所有人 xff08 前端开发人员 xff09 在我们的职业生涯中至少使用过几次的CSS属性之一 大多数人认为背景图像没有什么不寻常的 xff
  • 值得收藏的css grid构建复杂布局的小技巧!

    xff08 推荐教程 xff1a CSS教程 xff09 网格布局是现代CSS中最强大的功能之一 使用网格布局可以帮助我们在没有任何外部 UI 框架的情况下构建复杂的 快速响的布局 在这篇文章中 xff0c 将会介绍所有我们需要了解的 CS
  • 10个值得了解的Chrome开发工具和技巧

    1 模拟慢速网络和慢速设备 我们可能习惯了在城市的网速 xff0c 那是杠杠的 xff0c 并不意味网速在中国哪个都一样的 xff0c 在一些偏远地方 xff0c 网速依然慢的可怜 xff0c 所以有时候我们所做的产品是需要考虑网速慢的情况
  • JS中判断变量是否为数字方法

    推荐教程 xff1a JavaScript视频教程 JavaScript 是一种动态类型语言 xff0c 这意味着解释器在运行时确定变量的类型 实际上 xff0c 这也允许我们在相同的代码中使用相同的变量来存储不同类型的数据 如果没有文档和
  • vue+webpack2实现路由懒加载的方法介绍

    下面Vue js教程栏目给大家介绍一下vue 43 webpack2实现路由的懒加载的方法 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c 希望对大家有所帮助 当打包构建应用时 xff0c Javascript 包会变得
  • JS Math对象的10 个实用方法

    推荐教程 xff1a JavaScript视频教程 JavaScript中的math 对让我们能够对执行一些数学操作 它具有数学常数和函数的属性和方法 在今天的文章中将介绍 Math对象的一些有用方法 1 Math min Math min
  • PDF文档电子公章的初试

    PART 1 大家在日常生活中经常会接触到电子公章 xff0c 比如电子发票上一般会包含电子公章信息 xff0c 比如下图发票中就带有两个电子公章 xff0c 顶部的公章是普通的图形公章 xff0c 右下角的电子公章不仅包含图形公章还包含了
  • css grid构建复杂布局的小技巧

    xff08 推荐教程 xff1a CSS教程 xff09 网格布局是现代CSS中最强大的功能之一 使用网格布局可以帮助我们在没有任何外部 UI 框架的情况下构建复杂的 快速响的布局 在这篇文章中 xff0c 将会介绍所有我们需要了解的 CS
  • vue.js中使用v-for以及获取索引的方法介绍

    下面Vue js教程栏目带大家了解一下vue js中v for的使用及索引获取 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c 希望对大家有所帮助 2 x版本 xff1a v for 61 34 item index i
  • HTML网页自动跳转的5种方法

    xff08 推荐教程 xff1a html教程 xff09 在我们进行网站创建时经常会遇到需要进行网页跳转的情况 xff0c 本文就来为大家介绍五种网页自动跳转的方法 有一定的参考价值 xff0c 有需要的朋友可以参考一下 xff0c 希望
  • 深入讨论JavaScript中Set对象如何让代码更快

    我确信有很多开发人员坚持使用基本的全局对象 xff1a 数字 xff0c 字符串 xff0c 对象 xff0c 数组和布尔值 对于许多用例 xff0c 这些都是需要的 但是如果想让你的代码尽可能快速和可扩展 xff0c 那么这些基本类型并不