Skip to content

Commit

Permalink
perf: New implemention for Diff() (#191)
Browse files Browse the repository at this point in the history
Using set instead of nested for loops, the time complexity is reduced from O(n^2) to O(n)
  • Loading branch information
leilei3167 authored Mar 24, 2023
1 parent 7263418 commit a9ee294
Showing 1 changed file with 9 additions and 18 deletions.
27 changes: 9 additions & 18 deletions v2/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,25 @@ package pie
// The added and removed returned may be blank respectively, or contain upto as
// many elements that exists in the largest slice.
func Diff[T comparable](ss []T, against []T) (added, removed []T) {
// This is probably not the best way to do it. We do an O(n^2) between the
// slices to see which items are missing in each direction.

diffOneWay := func(ss1, ss2raw []T) (result []T) {
ss2 := make([]T, len(ss2raw))
copy(ss2, ss2raw)
set := make(map[T]struct{}, len(ss1))

for _, s := range ss1 {
found := false

for i, element := range ss2 {
if s == element {
ss2 = append(ss2[:i], ss2[i+1:]...)
found = true
break
}
}
set[s] = struct{}{}
}

if !found {
for _, s := range ss2raw {
if _, ok := set[s]; ok {
delete(set, s) // remove duplicates
} else {
result = append(result, s)
}
}

return
}

removed = diffOneWay(ss, against)
added = diffOneWay(against, ss)
added = diffOneWay(ss, against)
removed = diffOneWay(against, ss)

return
}

0 comments on commit a9ee294

Please sign in to comment.