在F#中使用最快元素查找的数据结构?

时间:2010-09-03 15:32:14

标签: data-structures f#

我正在尝试编写一个小型F#线性代数库(对于具有小矩阵的应用程序,因此内存不是问题),我想知道哪个数据结构在元素查找时间方面具有最佳性能特征,因为我需要它来定义矩阵运算?

3 个答案:

答案 0 :(得分:9)

我有点不清楚被问到了什么。

阵列当然是O(1),所以我希望它们是正确的答案。 (Brian的经验法则:如果你想要快速的东西,那么每种语言的答案都是一样的 - 使用一组结构。)

如果你需要更稀疏的东西,那就是.NET DictionaryHashSet类(使用散列),以及F#MapSet类型(使用树) /比较)。 Dictionary可能是次佳尝试。

但是我当然希望这要么取决于细节(密度,地点/访问模式......),要么根本不重要(其他因素压倒它)。

在一天结束时,就像每个表现问题一样:衡量

答案 1 :(得分:9)

如果“小”是2维或3维,那么结构。对于略大的“小”,请使用具有显式组件的引用类型。如果元素的数量超过大约30,那么使用单个数组并自己i + n*j。避免使用.NET的2D数组,因为它们比必要的慢几倍。真的避免使用F#的Matrix类型进行逐元素操作,因为它会像动态调度一样疯狂(速度慢一个数量级)。数组数组很好,但自己编制索引可以对索引进行更多的JIT优化。

答案 2 :(得分:2)

最有效的表示可能是一个可变数组(二维应该可以很好地工作)。索引的查找是O(1),因此它可以获得最高效率。即使数组是可变的,您仍然可以使用它来开发不可变(功能)矩阵类型 - 您需要做的就是避免变异数组。编译器不会检查这一点,但数据结构对于用户来说可以是纯粹的功能。

这样的事情可能是一个很好的起点:

// Constructor takes the data of the matrix
type Matrix(data:float[,]) =
  // Expose data only for private purposes (cannot be mutated by the user!)
  member private x.Data = data
  // All operations create new array as the result
  static member (+) (a:Matrix, b:Matrix) = 
    // TODO: Check that arrays have the same size
    let res = Array2D.init (a.Data.GetLength(0)) (a.Data.GetLength(1)) 
      (fun i j -> a.Data.[i, j] + a.Data.[i, j])
    new Matrix<_>(res)