【发布时间】:2011-04-07 22:14:55
【问题描述】:
我正在尝试编写一个小型 F# 线性代数库(对于具有小矩阵的应用程序,因此内存不是问题),我想知道哪种数据结构在元素查找时间方面具有最佳性能特征,因为我需要它来定义矩阵运算?
【问题讨论】:
标签: data-structures f#
我正在尝试编写一个小型 F# 线性代数库(对于具有小矩阵的应用程序,因此内存不是问题),我想知道哪种数据结构在元素查找时间方面具有最佳性能特征,因为我需要它来定义矩阵运算?
【问题讨论】:
标签: data-structures f#
如果“小”是 2 维或 3 维,则为结构。对于稍大的“小”,请使用带有显式组件的引用类型。如果元素数量超过 30 个,则使用单个数组并自己执行i + n*j。避免使用 .NET 的 2D 数组,因为它们比必要的慢几倍。真正避免 F# 的 Matrix 类型用于元素操作,因为它会做一些疯狂的事情,比如动态调度(慢一个数量级)。数组数组很好,但自己索引允许索引的更多 JIT 优化。
【讨论】:
我有点不清楚要问什么。
数组当然是 O(1),所以我希望它们是正确的答案。 (Brian 的经验法则:如果你想要快速的东西,那么每种语言的答案都是一样的——使用结构数组。)
如果您需要更稀疏的内容,可以使用 .NET Dictionary 和 HashSet 类(使用哈希),以及 F# Map 和 Set 类型(使用树/比较)。 Dictionary 可能是下一个最佳尝试。
但我当然希望这在很大程度上取决于具体情况(密度、位置/访问模式……),或者根本不重要(其他因素压倒它)。
在一天结束时,就像对于每个性能问题一样:衡量。
【讨论】:
最有效的表示可能是一个可变数组(二维应该可以很好地工作)。按索引查找是 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)
【讨论】: