如何使用 JavaScript Set 提高代码速度?
在编写代码时,我们始终努力使代码更易于阅读、更简单、更高效,以及更小巧。为此,我们遵循多种方法来提高代码效率。在本文中,我们将重点关注一些基于 Javascript Set 的技术,用于执行某些类似数组或基于集合的应用,这些应用将运行得更快,并且代码也将更加简洁。让我们关注一些用例。
Set 与数组有何不同以及使用 Set 相比数组的优势
数组是有索引的集合,其中每个元素都与特定索引相关联。另一方面,Set 是基于键的集合。在 Set 中,数据元素根据其键值进行排序。并且 Set 不允许重复,因此 Set 中的所有元素都是唯一的。使用 Set 有几个好处,可以使我们的代码运行更快。
要检查数组中是否存在某个元素,我们可以使用数组的 indexOf() 或 includes() 函数。与 Set 中的 has() 函数相比,这是一个较慢的操作。
我们可以使用其值从 Set 中删除元素。但在数组中,我们可以使用基于元素索引的 splice() 函数。因此,此操作也基于索引,这是一个较慢的过程。
类似地,使用 push() 或 unshift() 方法将元素插入数组的速度也比 Set 的插入操作慢。
在 Javascript 数组中不允许存储 NaN,但我们可以在 Set 中存储 NaN 值。
由于 Set 不允许重复元素,因此我们可以使用 Set 来去除重复项。方法很简单。我们将数组中存在的所有元素插入到 Set 中,无需检查任何条件,然后简单地从 Set 中取出所有元素。它将自动仅保留唯一元素,删除重复元素。
为什么 Set 比数组快
Javascript 数组上的大多数操作,如插入、删除、搜索等,都是线性时间操作。它们需要 O(n) 时间才能完成,其中 n 是数组的大小。但由于 Set 使用键来存储元素,因此大多数操作都需要常数时间 O(1)。因此,Set 的大小不会影响 Set 集合的性能。现在让我们看一些示例来分析 Set 在 Javascript 中的速度有多快。
Set 和数组极端性能测试的初始设置
我们正在创建一个包含 1000000 个元素的数组和一个 Set。它们从 0 到 999999 开始。然后,我们将对这些数据结构执行不同的测试。
代码
let A = [] S = new Set() size = 1000000; for (let i = 0; i < size; i++) { A.push(i); S.add(i); }
项目搜索性能测试
让我们在数组和 Set 中找到一个元素,例如 56420。我们还显示执行此操作所需的时间。从时间值中,我们可以很容易地理解它们花费了多少时间,因此哪一个花费的时间更少,性能就更好。
注意 - 这些代码示例的结果无法在 HTML 页面上显示。要获取结果,您需要在本地文件上运行这些脚本,并在浏览器中从 Javascript 控制台检查结果。
示例
let A = [] S = new Set() size = 1000000; for (let i = 0; i < size; i++) { A.push(i); S.add(i); } let res; let toSearch = 56420; console.time( 'ArrTime' ); res = A.indexOf( toSearch ) !== -1; console.timeEnd( 'ArrTime' ); console.time( 'SetTime' ); res = S.has( toSearch ); console.timeEnd( 'SetTime' );
在不同的系统和浏览器中,时间可能会有所不同,但数组始终比 Set 花费的时间更长。在此示例中,在代码执行时,数组搜索花费了 0.172ms 的时间,而 Set 花费了 0.008ms 的时间,快了近 21 倍。
项目插入性能测试
让我们来看另一个类似的示例,我们将在其中将一个元素插入到 Set 和数组中,然后根据执行时间分析它们的性能。
示例
let A = [] S = new Set() size = 1000000; for (let i = 0; i < size; i++) { A.push(i); S.add(i); } console.time( 'ArrTimeInsert' ); A.push( size ); console.timeEnd( 'ArrTimeInsert' ); console.time( 'SetTimeInsert' ); S.add( size ); console.timeEnd( 'SetTimeInsert' );
数组插入花费了 0.140ms,Set 插入花费了 0.009ms。在这里,我们也可以看到 Set 的性能更好,并且比数组快 15.5 倍。
项目删除性能测试
对元素删除进行类似的测试。在 Javascript 中从数组中删除元素不是一个简单的过程。从给定索引中删除元素需要几个步骤。对于 Set,我们可以使用 delete() 方法使用值进行删除。让我们查看代码以更好地理解。
示例
let A = [] S = new Set() size = 1000000; for (let i = 0; i < size; i++) { A.push(i); S.add(i); } function deleteFromArray(array, element){ let idx = array.indexOf(element); return idx !== -1 && array.splice(idx, 1); } let res; let toDelete = 56420; console.time( 'ArrTimeDelete' ); res = deleteFromArray( A, toDelete); console.timeEnd( 'ArrTimeDelete' ); console.time( 'SetTimeDelete' ); res = S.delete( toDelete ); console.timeEnd( 'SetTimeDelete' );
数组删除花费了 1.09ms,但这不是实际的删除时间。两个操作合并了。这里首先,我们找到给定元素的索引,然后执行删除操作。对于 Set,它花费的时间几乎与其他操作相同,这确保了 Set 操作需要常数时间才能执行。
结论
在为大型应用程序开发系统时,系统的性能应在所有领域都非常高效。编写更快、更高效的代码始终是开发人员的良好实践。本文介绍了在 Javascript 中使用 Set 数据结构而不是数组数据结构以提高其性能的好处。Javascript 数组操作(如插入、删除和搜索)需要线性时间,这取决于数组中存在的元素数量,另一方面,Set 使用常数时间算法来执行这些操作。Set 基于键存储数据,这使得搜索、插入和删除变得高效。数组使用基于索引的方法,在实践中会降低上述操作的性能。