Shift-To-Middle Array:有前景的資料結構因增長問題面臨批評

BigGo Editorial Team
Shift-To-Middle Array:有前景的資料結構因增長問題面臨批評

最近推出的 Shift-To-Middle Array 資料結構在開發者中引發了廣泛討論,儘管概念有前景,但許多人指出了其關鍵缺陷。這種新實現旨在作為傳統資料結構(如 std::dequestd::vector 和連結串列)的替代方案,目標是最佳化兩端的插入和刪除操作,同時保持連續的記憶體儲存。

發現無限增長問題

最主要的批評集中在一個基本設計缺陷上:該資料結構在常見佇列操作中會無限增長。正如一位開發者在討論中指出,重複地在頭部推入元素並從尾部移除元素——一種標準的佇列模式——會導致陣列持續調整大小,即使陣列中維持的元素數量很小且恆定。

「如果你重複地在頭部推入元素並從尾部移除元素,即使陣列中的最大元素數量很小,這種實現也會無限增長。」

這種行為與環形緩衝區實現形成鮮明對比,後者能夠高效處理這種常見用例,無需不必要的記憶體分配或資料複製。這個增長問題實際上削弱了該資料結構在其主要預期應用之一(高效能佇列)中的可行性。

Shift-To-Middle Array 的關鍵特性

  • 兩端插入和刪除的平攤時間複雜度為 O(1)
  • 快速隨機訪問(O(1))
  • 比連結串列有更好的快取區域性性
  • 支援 SIMD 和並行最佳化
  • 連續記憶體儲存(不像 std::deque 的分段塊儲存)

主要批評

  • 在佇列式操作下無限增長(頭部推入,尾部彈出)
  • 對非平凡型別存在問題(解構函式,移動建構函式)
  • 與環形緩衝區實現相比存在不必要的複製
  • 缺乏高效的隨機刪除操作
  • 缺少迭代器支援,無法相容標準演算法

對非平凡型別的實現擔憂

幾位開發者指出,當前的 C++ 實現在處理非平凡型別時會面臨問題。具有解構函式或移動建構函式(如 std::unique_ptr)的物件可能會導致問題,因為該實現似乎是在原始記憶體上操作。一位評論者建議至少新增一個靜態斷言來限制使用於可平凡複製的型別,突顯了當前實現的侷限性。

與現有解決方案的比較

社群討論揭示了關於替代實現的有趣見解。一些人指出類似的方法已經存在,包括 Apple 的 CoreFoundation CFArray 和 Boost 的 devector。其他人則質疑這種新結構是否比已建立的解決方案(如 VecDeque,一種環形緩衝區實現)提供了有意義的優勢。

幾位開發者分享了他們自己實現的類似資料結構,表明這個概念本身有價值,但需要仔細考慮邊緣情況和效能特性。

效能權衡

雖然 Shift-To-Middle Array 承諾比連結串列有更好的快取區域性性,並且在兩端都能進行高效操作,但討論強調了重要的效能權衡。該結構在調整大小時將元素移動到中間的方法涉及複製操作,而直接的環形緩衝區則避免了這一點。

一些開發者表示,索引環形緩衝區可能會因為需要分支或取模操作來處理環繞而略微增加成本,但其他人指出,由於指令流水線的原因,這種小差異通常會消失。沒有比較常見用例的全面基準測試,很難確定哪種方法在實踐中表現更好。

替代方法

討論執行緒揭示了幾種解決類似問題的替代方法。一位開發者描述了一種雙端向量,在兩端保持空閒空間,只儲存一個指標和三個長度(總大小為32位元組,相比 Vec 通常的24位元組)。另一位提到使用記憶體對映技巧建立具有連續檢視的環形緩衝區,儘管這種方法有其自身與頁面大小和系統呼叫開銷相關的限制。

Shift-To-Middle Array 是資料結構領域的一個有趣補充,但其當前實現在常見用例中表現不佳。與許多專用資料結構一樣,最佳選擇很大程度上取決於特定的應用需求、訪問模式和效能特性。考慮使用此結構的開發者應仔細評估其優勢是否超過已識別的侷限性,特別是佇列類操作的令人擔憂的增長行為。

參考:Shift-To-Middle Array