agnivade / levenshtein

Go implementation to calculate Levenshtein Distance.
MIT License
358 stars 28 forks source link

Optimization #21

Closed nicola-spb closed 2 years ago

nicola-spb commented 2 years ago

Hello,

Mini optimization. Replace this:

// swap to save some memory O(min(a,b)) instead of O(a)
if len(s1) > len(s2) {
    s1, s2 = s2, s1
}
lenS1 := len(s1)
lenS2 := len(s2)

To:

lenS1 := len(s1)
lenS2 := len(s2)
if lenS1 > lenS2 {
    s1, s2 = s2, s1
    lenS1 = len(s1)
    lenS2 = len(s2)
}
agnivade commented 2 years ago

Interesting, could you post some benchmarks showing the improvement?

nicola-spb commented 2 years ago

Strange but your variant is worked better

var data = [][]string{
    {"ss","dd"},
    {"ddtgryryrrdfryyrryryy","ddttryryrrryryyrryryy"},
    {"ddtgryryrrdfryyrryryyddtgryryrrdfryyrryryy","ddttryryrrryryyrryryyddttryryrrryryyrryryy"},    {"ddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryy","ddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryy"},
    {"ddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryyddtgryryrrdfryyrryryy","ddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryyddttryryrrryryyrryryy"},
}

func BenchmarkDist1(b *testing.B) {
    for n := 0; n < b.N; n++ {
        for _, d := range data {
            ComputeDistance1(d[0], d[1])
        }
    }
}

func BenchmarkDist2(b *testing.B) {
    for n := 0; n < b.N; n++ {
        for _, d := range data {
            ComputeDistance2(d[0], d[1])
        }
    }
}
BenchmarkDist1-4                   18402             70557 ns/op
BenchmarkDist2-4                   15075             88472 ns/op
agnivade commented 2 years ago

I wouldn't expect this much of a difference. Just running the benchmark once is not accurate enough. Usually microbenchmarks are compared by running the benchmark atleast 10 times on a quiet system with nothing else running and using the benchstat tool to compare them.

Looking at your code, all we are saving is 2 len calls in the best case. I'd have to look at the exact assembly but those should just be some extra register moves.

But I'd be curious to see a proper benchmark comparison using benchstat.

agnivade commented 2 years ago

No further updates. Closing this. Please feel free to post the benchmark comparison showing improvement.