我正在研究一個將需要Levenshtein算法來計算兩個字符串的相似度的應用程序。相同算法的兩個實現之間的性能差異
隨着前段時間我適應一個C#版本(這可以很容易找到在互聯網上四處傳播)到VB.NET和它看起來像這樣:
Public Function Levenshtein1(s1 As String, s2 As String) As Double
Dim n As Integer = s1.Length
Dim m As Integer = s2.Length
Dim d(n, m) As Integer
Dim cost As Integer
Dim s1c As Char
For i = 1 To n
d(i, 0) = i
Next
For j = 1 To m
d(0, j) = j
Next
For i = 1 To n
s1c = s1(i - 1)
For j = 1 To m
If s1c = s2(j - 1) Then
cost = 0
Else
cost = 1
End If
d(i, j) = Math.Min(Math.Min(d(i - 1, j) + 1, d(i, j - 1) + 1), d(i - 1, j - 1) + cost)
Next
Next
Return (1.0 - (d(n, m)/Math.Max(n, m))) * 100
End Function
然後,試圖調整,並改善其性能,I與版本結束:
Public Function Levenshtein2(s1 As String, s2 As String) As Double
Dim n As Integer = s1.Length
Dim m As Integer = s2.Length
Dim d(n, m) As Integer
Dim s1c As Char
Dim cost As Integer
For i = 1 To n
d(i, 0) = i
s1c = s1(i - 1)
For j = 1 To m
d(0, j) = j
If s1c = s2(j - 1) Then
cost = 0
Else
cost = 1
End If
d(i, j) = Math.Min(Math.Min(d(i - 1, j) + 1, d(i, j - 1) + 1), d(i - 1, j - 1) + cost)
Next
Next
Return (1.0 - (d(n, m)/Math.Max(n, m))) * 100
End Function
基本上,我想的,而不是需要兩個初始(和附加)循環該距離d()的陣列可以在主要爲週期內進行初始化。我真的認爲這將是一個巨大的進步......不幸的是,它不僅沒有改善原來的效果,反而變慢了!
我已經試着通過查看生成的IL代碼來分析兩個版本,但我無法理解它。
所以,我希望有人能夠解釋這個問題,並解釋爲什麼第二個版本(即使它的週期較少)運行速度比原來慢?
注:時間差約爲0.15納秒。這看起來並不多,但是當你必須檢查數千萬個字符串時......差異變得相當顯着。
我怎麼錯過那!? 非常感謝! – xfx
我剛剛將循環內部的行的初始化移動了一遍,現在第二個版本的算法比原始版本快了40% - 所以再次感謝您! (我生我的氣,因爲沒有看到!) – xfx