簡體   English   中英

Haskell中具有高性能的可變隨機訪問數組/向量

[英]Mutable, random-access array/vector with high performance in haskell

這個關於Haskell的主題討論了很多(例如可變數組實現 ),但我仍然不確定需要頻繁修改和隨機訪問數組/向量的情況的最佳實踐是什么。

說一個長度為1,000,000的向量。 對它的操作涉及根據輸入訪問其(較小的,例如1000個)子集,並根據輸入修改值。 此外,這種操作重復2,000,000次。 任務本身可以在純數據結構中實現,例如列表,如下所示,盡管效率很低:

type Vect = [Int]

f :: Vect -> [[Int]] -> Vect
f x indsList = foldl g x indsList

-- g is just an example of random-access and modifications on the values.
g :: Vect -> [Int] -> Vect
g x inds = map h $ zip x [0..]
    where h (x, i) = if i `elem` inds then x !! i + 1 else x !! i

散列/映射數據結構(例如IntMap)可以用於有效的大量隨機訪問,但是數組/向量也應該這樣做。 更重要的是,仍需要通過可變結構來解決大量修改以避免存儲器復制。 Haskell中是否存在可變的隨機訪問數組/向量? 如果使用ST / IO Monads,這些控件會影響我的設置嗎?

Haskell確實具有有效的可變數組。

  • STUArray ,它具有相當復雜但通常只是不必要的Ix索引方法,具有許多邊界檢查和很少的特殊優化,這使其比理論上的速度慢一些。

  • 所有Data.Vector開銷都很少,大量使用了流融合優化,更喜歡簡單的“類似於列表”的界面。 這意味着您實際上可以非常輕松地將示例直接輕松地轉換為不可變向量,並且可能仍會獲得比預期更好的性能:

     import Data.Vector.Unboxed as VU type Vect = VU.Vector Int f :: Vect -> [[Int]] -> Vect fx indsList = VU.foldl gx indsList g :: Vect -> [Int] -> Vect gx inds = VU.zipWith hx [0..] -- h is just an example of modifications on the values. where hxi | i`elem`inds = x VU.! i + 1 | otherwise = x VU.! i 

是的,您可能想在ST monad中進行可變更新。 不知道您所說的“這樣的控件會影響性能”是什么意思:一旦編譯器優化了行之有效的類型安全性,命令語言就不會真正沒有任何“控件”。 哪個GHC可以做得很好; 使用Data.Vector.Unboxed可以非常接近C的性能。 總會有一些不可避免的開銷,但這主要與垃圾回收等問題有關,您在Java中也會遇到這種問題。

由於STIO是monad,因此編譯器實際上可以進行一些更高級的優化,這在命令式語言中是不可能的,盡管編譯器的作用還不是很遠。

在許多地方都討論了性能,尤其是陣列操作的性能,例如在RWH中

來自Yarr的外來UArrays是可變的,隨機訪問和最大快速。 它們也是“快速和臟”的,即不對每次突變操作施加冷凍/解凍樣板。

缺點:幾乎所有“低級”操作都在IO之下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM