Haskell Data.Memocombinators 性能问题?
Haskell Data.Memocombinators performance issues?
_
你好,
部分my program to compute differences between files使用标准DP算法计算两个列表之间的最长公共非连续子序列。我一直 运行 遇到一些此功能的性能问题,所以我 运行 HPC 进行分析,并发现以下结果:
individual inherited
COST CENTRE no. entries %time %alloc %time %alloc
(ommitted lines above)
longestCommonSubsequence 1 0.0 0.0 99.9 100.0
longestCommonSubsequence' 8855742 94.5 98.4 99.9 100.0
longestCommonSubsequence'' 8855742 4.2 0.8 5.4 1.6
longestCommonSubsequence''.caseY 3707851 0.6 0.6 0.6 0.6
longestCommonSubsequence''.caseX 3707851 0.6 0.2 0.6 0.2
(ommitted lines below)
这是有问题的代码:
longestCommonSubsequence' :: forall a. (Eq a) => [a] -> [a] -> Int -> Int -> [a]
longestCommonSubsequence' xs ys i j =
(Memo.memo2 Memo.integral Memo.integral (longestCommonSubsequence'' xs ys)) i j
longestCommonSubsequence'' :: forall a. (Eq a) => [a] -> [a] -> Int -> Int -> [a]
longestCommonSubsequence'' [] _ _ _ = []
longestCommonSubsequence'' _ [] _ _ = []
longestCommonSubsequence'' (x:xs) (y:ys) i j =
if x == y
then x : (longestCommonSubsequence' xs ys (i + 1) (j + 1)) -- WLOG
else if (length caseX) > (length caseY)
then caseX
else caseY
where
caseX :: [a]
caseX = longestCommonSubsequence' xs (y:ys) (i + 1) j
caseY :: [a]
caseY = longestCommonSubsequence' (x:xs) ys i (j + 1)
我发现值得注意的是,所有的时间和内存使用都发生在 longestCommonSubsequence'
记忆包装器中。因此,我会得出结论,性能下降来自 Data.Memocombinators
完成的所有查找和缓存,尽管它在我使用它的许多其他时间里总是表现出色。
我想我的问题是……这个结论似乎是合理的;是吗?如果是这样,那么有人对其他实现 DP 的方法有什么建议吗?
作为参考,比较两个 14 行长的文件的内容分别为 "a\nb\nc\n...m"
和 "*a\nb\nc\n...m*"
(内容相同但 '*'
预挂和 post-挂起)。
提前致谢! :)
编辑:现在尝试 ghc-core
东西; post 如果我能让它很好地与 Cabal 项目一起玩并获得任何有用的信息,我会更新!
当您调用 Memo.memo2 Memo.integral Memo.integral (longestCommonSubsequence'' xs ys)
时,它会为函数 longestCommonSubsequence'' xs ys
创建一个记忆器。这意味着 xs
和 ys
的每个不同值都有一个 memoizer。我想大部分执行时间都花在了为所有这些记忆器创建所有这些数据结构上。
您是要记住 longestCommonSubsequence''
的 4 个参数吗?
_
你好,
部分my program to compute differences between files使用标准DP算法计算两个列表之间的最长公共非连续子序列。我一直 运行 遇到一些此功能的性能问题,所以我 运行 HPC 进行分析,并发现以下结果:
individual inherited
COST CENTRE no. entries %time %alloc %time %alloc
(ommitted lines above)
longestCommonSubsequence 1 0.0 0.0 99.9 100.0
longestCommonSubsequence' 8855742 94.5 98.4 99.9 100.0
longestCommonSubsequence'' 8855742 4.2 0.8 5.4 1.6
longestCommonSubsequence''.caseY 3707851 0.6 0.6 0.6 0.6
longestCommonSubsequence''.caseX 3707851 0.6 0.2 0.6 0.2
(ommitted lines below)
这是有问题的代码:
longestCommonSubsequence' :: forall a. (Eq a) => [a] -> [a] -> Int -> Int -> [a]
longestCommonSubsequence' xs ys i j =
(Memo.memo2 Memo.integral Memo.integral (longestCommonSubsequence'' xs ys)) i j
longestCommonSubsequence'' :: forall a. (Eq a) => [a] -> [a] -> Int -> Int -> [a]
longestCommonSubsequence'' [] _ _ _ = []
longestCommonSubsequence'' _ [] _ _ = []
longestCommonSubsequence'' (x:xs) (y:ys) i j =
if x == y
then x : (longestCommonSubsequence' xs ys (i + 1) (j + 1)) -- WLOG
else if (length caseX) > (length caseY)
then caseX
else caseY
where
caseX :: [a]
caseX = longestCommonSubsequence' xs (y:ys) (i + 1) j
caseY :: [a]
caseY = longestCommonSubsequence' (x:xs) ys i (j + 1)
我发现值得注意的是,所有的时间和内存使用都发生在 longestCommonSubsequence'
记忆包装器中。因此,我会得出结论,性能下降来自 Data.Memocombinators
完成的所有查找和缓存,尽管它在我使用它的许多其他时间里总是表现出色。
我想我的问题是……这个结论似乎是合理的;是吗?如果是这样,那么有人对其他实现 DP 的方法有什么建议吗?
作为参考,比较两个 14 行长的文件的内容分别为 "a\nb\nc\n...m"
和 "*a\nb\nc\n...m*"
(内容相同但 '*'
预挂和 post-挂起)。
提前致谢! :)
编辑:现在尝试 ghc-core
东西; post 如果我能让它很好地与 Cabal 项目一起玩并获得任何有用的信息,我会更新!
当您调用 Memo.memo2 Memo.integral Memo.integral (longestCommonSubsequence'' xs ys)
时,它会为函数 longestCommonSubsequence'' xs ys
创建一个记忆器。这意味着 xs
和 ys
的每个不同值都有一个 memoizer。我想大部分执行时间都花在了为所有这些记忆器创建所有这些数据结构上。
您是要记住 longestCommonSubsequence''
的 4 个参数吗?