【问题标题】:The data structure with the fastest element lookup in F#?F#中元素查找速度最快的数据结构?
【发布时间】:2011-04-07 22:14:55
【问题描述】:

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

【问题讨论】:

    标签: data-structures f#


    【解决方案1】:

    如果“小”是 2 维或 3 维,则为结构。对于稍大的“小”,请使用带有显式组件的引用类型。如果元素数量超过 30 个,则使用单个数组并自己执行i + n*j。避免使用 .NET 的 2D 数组,因为它们比必要的慢几倍。真正避免 F# 的 Matrix 类型用于元素操作,因为它会做一些疯狂的事情,比如动态调度(慢一个数量级)。数组数组很好,但自己索引允许索引的更多 JIT 优化。

    【讨论】:

    • 简明扼要。不过,到处都是很好的答案,我会回来参考的:)
    【解决方案2】:

    我有点不清楚要问什么。

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

    如果您需要更稀疏的内容,可以使用 .NET DictionaryHashSet 类(使用哈希),以及 F# MapSet 类型(使用树/比较)。 Dictionary 可能是下一个最佳尝试。

    但我当然希望这在很大程度上取决于具体情况(密度、位置/访问模式……),或者根本不重要(其他因素压倒它)。

    在一天结束时,就像对于每个性能问题一样:衡量

    【讨论】:

    • 我投了赞成票,因为 Brian 的经验法则。当我到达终点时,我想投票 measure。很好的答案。
    • 我同意;高效代码的三个基本要素是:基准、基准、基准。
    【解决方案3】:

    最有效的表示可能是一个可变数组(二维应该可以很好地工作)。按索引查找是 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)
    

    【讨论】:

    • 据我了解,在 .NET 中,多维数组比一维数组慢得多,这一点需要牢记。
    • @kvb:很有趣。我不知道 - 你有什么参考吗?这是否适用于矩形二维数组和“数组数组”?
    • 我认为锯齿状数组(即数组的数组)的性能相当不错。然而,真正的多维数组并没有得到很好的优化。我没有很好的参考资料,但请参阅例如stackoverflow.com/questions/468832/….
    猜你喜欢
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多