当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 使用toList是不是很糟糕?

来源:互联网 收集:自由互联 发布时间:2021-06-22
假设2个地图 import qualified Data.Map as Msparse1, sparse2 :: M.Map Int Floatsparse1 = M.fromList [(1,2.0),(10,3),(12,5),(100,7),(102,11)]sparse2 = M.fromList [(2,13.0),(11,17),(12,19),(101,23),(102,29)] 你如何定义一个优雅的功
假设2个地图

import qualified Data.Map as M
sparse1, sparse2 :: M.Map Int Float
sparse1 = M.fromList [(1,2.0),(10,3),(12,5),(100,7),(102,11)]
sparse2 = M.fromList [(2,13.0),(11,17),(12,19),(101,23),(102,29)]

你如何定义一个优雅的功能

combi :: M.Map Int Float -> M.Map Int Float -> Float

这样,combi sparse1 sparse2返回414.0(= 5 * 19 11 * 29)因为12和102是这两个映射的唯一公共密钥?有一个优雅(简单和有效)的功能列表,因为这些将严格排序:

combiList xs ys = cL xs ys 0
cL [] _ acc = acc
cL _ [] acc = acc
cL (x@(k,r):xs) (y@(k',r'):ys) acc 
    | k < k'  = cL xs     (y:ys) acc
    | k == k' = cL xs     ys     (acc+r*r')
    | k > k'  = cL (x:xs) ys     acc

但是

combi m1 m2 = combiList (M.toList m1) (M.toList m2)

一个好主意知道列表不再用于其余的代码?如果没有,你如何在没有toList的情况下有效地编写combi?

在地图上使用fold和intersectWith更优雅(并且可能更快):

combi :: M.Map Int Float -> M.Map Int Float -> Float
combi x y = M.fold (+) 0 $M.intersectionWith (*) x y

combi sparse1 sparse2根据需要返回414.0.

如果您关心性能,请尝试使用Data.IntMap:它应该比Data.Map快几倍.

网友评论