为了使用键引用一些坐标,我想使用可区分的联合类型,因为它们允许各种有效的模式匹配。
考虑以下代码片段:
[<CustomEquality; CustomComparison>]
type Coord =
| Spot of AssetKey
| Vol of AssetKey * DateTime option
| Rate of Currency
.....
member this.sortKey =
match this with
| Spot(key) -> (0 , key.toString)
| Vol(key) -> (1 , key.toString)
| Vol(key, Some(t)) -> (2 , key.toString + t.ToShortString())
| Rate(cur) -> (3 , cur.toString)
......
interface IComparable with
member this.CompareTo(obj) =
match obj with
| :? Coord as other -> compare this.sortKey other.sortKey
| _ -> invalidArg "obj" "not a Coord type"
override this.Equals(obj) =
match obj with
| :? Coord as other -> this.sortKey = other.sortKey
| _ -> false
override this.GetHashCode() = this.sortKey.GetHashCode()
我需要强制执行特定的排序顺序。例如 Spot < Vol 总是。我使用 sortKey 成员函数强制执行此操作。
AssetKey 又是一个非常相似的可区分联合类型:
[<StructuralEqualityAttribute; StructuralComparisonAttribute>]
type AssetKey =
| Equity of string
| EquityIndex of string
.....
所以这一切都很好,但它很慢。据我所见,如果调用 sortKey 函数,则会再次构建整个键,特别是再次调用 toString 函数。
一个明显的改进是添加一个缓存层,这更像是一种破解而不是一种解决方案。
进一步的优化是在字符串上使用哈希键。但是在这里我需要再次添加缓存,因为我需要缓存哈希键并且我不想重新计算它。
如果我使用结构或类,性能优化会更容易,但是我会失去模式匹配的灵活性,例如
match c with
| Coord.Vol(ak, _) when ak = assetKey -> true
| _ -> false
什么是另一种表现良好的替代方法?在我的某些时间里,sortKey 函数损失了 30% 甚至更多的整体性能。
感谢您的任何建议和改进。