如何使用 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 基於鍵儲存資料,這使得搜尋、插入和刪除變得高效。陣列使用基於索引的方法,在實踐中會降低上述操作的效能。

更新於:2022年8月23日

1K+ 閱讀量

開啟您的 職業生涯

透過完成課程獲得認證

立即開始
廣告