Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hash 实现区分联合类型的快速CustomEquality和CustomComparison_Hash_F#_Pattern Matching_Equality_Discriminated Union - Fatal编程技术网

Hash 实现区分联合类型的快速CustomEquality和CustomComparison

Hash 实现区分联合类型的快速CustomEquality和CustomComparison,hash,f#,pattern-matching,equality,discriminated-union,Hash,F#,Pattern Matching,Equality,Discriminated Union,对于使用键引用某些坐标,我希望使用区分的联合类型,因为它们允许各种类型的有效模式匹配 考虑以下代码snipet: [<CustomEquality; CustomComparison>] type Coord = | Spot of AssetKey | Vol of AssetKey * DateTime option | Rate of Currency ..... member this.sor

对于使用键引用某些坐标,我希望使用区分的联合类型,因为它们允许各种类型的有效模式匹配

考虑以下代码snipet:

[<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()
另一种表现良好的方法是什么?在我的一些计时中,sortKey功能会损失30%甚至更多的整体性能


谢谢你的建议和改进

简单优化
您可以轻松完成的一个基本优化是,当您可以仅根据
Coord
的类型做出决策时,避免调用
toString
。您可以编写以下内容,而不是构建
sortKey

// Separate functions that return tag and key, so that we don't
// have to call 'toString' if we can decide based just on the Tag
member this.Tag = 
    match this with 
    | Spot _ -> 0 | Vol(_, None) -> 1 
    | Vol _ -> 2 | Rate _ -> 3
member this.Key = 
    match this with 
    | Spot(key) | Vol(key, None) -> key.toString | Rate cur -> cur.toString
    | Vol(key, Some t) -> key.toString + t.ToShortString())  

interface IComparable with  
    member this.CompareTo(obj) =  
        match obj with  
        | :? Coord as other -> 
            let c = compare this.Tag other.Tag
            // Try comparing based on the tag first - if the tags 
            // are the same, then get Key and compare based on the key
            if c <> 0 then c else compare this.Key other.Key
        | _ -> invalidArg "obj" "not a Coord type" 
给定类型为
AssetKey
的值,您现在可以编写
k.Key
来获取缓存的字符串表示形式,并可以使用活动模式对其进行模式匹配:

match k with 
| Equity k -> ...
| EquityIndex i -> ...

你可以考虑做一些像

之类的事情。
type CoordRepr =
| Spot of AssetKey 
| Vol of AssetKey * DateTime option  
| Rate of Currency              

let sortKey = function
| Spot(key) -> 1,key.ToString()
| Vol(key,None) -> 2,key.ToString()
| Vol(key,Some(v)) -> 2,key.ToString() + v.ToShortDateString()
| Rate(key) -> 3,key.ToString()

type Coord(repr) =
    let sortKey = sortKey repr
    member __.Repr = repr
    member __.SortKey = sortKey
    override __.Equals(that) =
        match that with
        | :? Coord as c -> sortKey = c.SortKey
        | _ -> false
    override __.GetHashCode() = sortKey.GetHashCode()
    interface System.IComparable with
        member __.CompareTo(that) =
            match that with
            | :? Coord as c -> compare sortKey c.SortKey
            | _ -> failwith "invalidArg"

let Spot k = Coord(Spot k)
let Vol(k,v) = Coord(Vol(k,v))
let Rate(k) = Coord(Rate(k))

let (|Spot|Vol|Rate|) (c:Coord) =
    match c.Repr with
    | Spot k -> Spot k
    | Vol(k,v) -> Vol(k,v)
    | Rate k -> Rate k

然后使用签名文件隐藏
CoordRepr
Coord
的构造函数,
sortKey
,等等。

谢谢您的帮助。我实现了第一个版本,速度快了大约100倍。以下是我的实现:
// This type will not be used directly - it is an internal implementation
// hidden from the users that will be accessed using active patterns
[<RequiresQualifiedAccess>]
type AssetKeyInternal =       
  | Equity of string       
  | EquityIndex of string  
  override x.ToString() = ...

// Public type with active patterns for pattern matching
type AssetKey(key:AssteKeyInternal) = 
  let str = lazy key.ToString() // Lazily cached string
  member x.Key = str.Value      // Evaluated when accessed for the first time

  member x.Value = key // Returns the internal representation

// Define active patterns working over AssetKey type
let (|Equity|EquityIndex|) (k:AssetKey) =
  match k.Value with
  | AssetKeyInternal.Equity(e) -> Equity(e)
  | AssetKeyInternal.EquityIndex(e) -> EquityIndex(e)
match k with 
| Equity k -> ...
| EquityIndex i -> ...
type CoordRepr =
| Spot of AssetKey 
| Vol of AssetKey * DateTime option  
| Rate of Currency              

let sortKey = function
| Spot(key) -> 1,key.ToString()
| Vol(key,None) -> 2,key.ToString()
| Vol(key,Some(v)) -> 2,key.ToString() + v.ToShortDateString()
| Rate(key) -> 3,key.ToString()

type Coord(repr) =
    let sortKey = sortKey repr
    member __.Repr = repr
    member __.SortKey = sortKey
    override __.Equals(that) =
        match that with
        | :? Coord as c -> sortKey = c.SortKey
        | _ -> false
    override __.GetHashCode() = sortKey.GetHashCode()
    interface System.IComparable with
        member __.CompareTo(that) =
            match that with
            | :? Coord as c -> compare sortKey c.SortKey
            | _ -> failwith "invalidArg"

let Spot k = Coord(Spot k)
let Vol(k,v) = Coord(Vol(k,v))
let Rate(k) = Coord(Rate(k))

let (|Spot|Vol|Rate|) (c:Coord) =
    match c.Repr with
    | Spot k -> Spot k
    | Vol(k,v) -> Vol(k,v)
    | Rate k -> Rate k