我是新來的haskell,我遇到了一個非常嚴重的性能問題,它必須是我的代碼而不是haskell平臺。Levenshtein距離成本
我有一個levenshtein距離(自己的代碼)的python實現,我通過(或試圖這樣做)這個給haskell。結果是如下:現在
bool2int :: Bool -> Int
bool2int True = 1
bool2int False = 0
levenshtein :: Eq a => [a] -> [a] -> Int -> Int -> Int
levenshtein u v 0 0 = 0
levenshtein u v i 0 = i
levenshtein u v 0 j = j
levenshtein u v i j = minimum [1 + levenshtein u v i (j - 1),
1 + levenshtein u v (i - 1) j,
bool2int (u !! (i - 1) /= v !! (j - 1)) + levenshtein u v (i - 1) (j - 1) ]
distance :: Eq a => [a] -> [a] -> Int
distance u v = levenshtein u v (length u) (length v)
,對於長度爲10或更多的串中執行時間的差的蟒和Haskell之間的10各種權力。還有一些粗糙的時間測量(掛鐘,因爲我還沒有在haskell中發現一個clock()命令),似乎我的haskell實現並沒有花費O(mn),而是其他一些其他的高速增長的成本。
注意:我不希望我的haskell實現與Python腳本競爭速度。我只是希望它運行在一個「明智」的時間,而不是整個宇宙存在的時間的倍數。
問題:
- 我在做什麼錯了,我的實現是這麼混賬的慢?
- 如何解決?
- 談到「懶惰評價」:我認爲如果
levenshtein "cat" "kit" 2 2
被稱爲三次,它只計算一次。這是正確的嗎? - 我的bool2int必須有內置的東西,對不對?
- 任何其他意見,如果它推動我在粗略的道路上掌握Haskell前進高度讚賞。
編輯:這裏去的Python代碼進行比較:
#! /usr/bin/python3.2
# -*- coding, utf-8 -*-
class Levenshtein:
def __init__ (self, u, v):
self.__u = ' ' + u
self.__v = ' ' + v
self.__D = [ [None for x in self.__u] for x in self.__v]
for x, _ in enumerate (self.__u): self.__D [0] [x] = x
for x, _ in enumerate (self.__v): self.__D [x] [0] = x
@property
def distance (self):
return self.__getD (len (self.__v) - 1, len (self.__u) - 1)
def __getD (self, i, j):
if self.__D [i] [j] != None: return self.__D [i] [j]
self.__D [i] [j] = min ([self.__getD (i - 1, j - 1) + (0 if self.__v [i] == self.__u [j] else 1),
self.__getD (i, j - 1) + 1,
self.__getD (i - 1, j) + 1])
return self.__D [i] [j]
print (Levenshtein ('first string', 'second string').distance)
看一看以下問題(由我): http://stackoverflow.com/questions/5515025/edit-distance-algorithm-in-haskell-performance-tuning - 它實際上是相同的問題 – bzn
你可以發佈Python公司德比較? – hammar
很快就會做。 – Hyperboreus