Skip to content

Commit

Permalink
refactor: optimize insertion sort
Browse files Browse the repository at this point in the history
  • Loading branch information
wI2L committed May 7, 2023
1 parent 3ad7b8c commit d28c8f7
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 10 deletions.
14 changes: 4 additions & 10 deletions differ.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,24 +386,18 @@ func (d *Differ) applyOpts(opts ...Option) {
}

func sortStrings(v []string) {
if len(v) < 20 {
if len(v) <= 20 {
insertionSort(v)
} else {
sort.Strings(v)
}
}

func insertionSort(v []string) {
for j := 1; j < len(v); j++ {
// Invariant: v[:j] contains the same elements as
// the original slice v[:j], but in sorted order.
key := v[j]
i := j - 1
for i >= 0 && v[i] > key {
v[i+1] = v[i]
i--
for i := 0; i < len(v); i++ {
for j := i; j > 0 && v[j-1] > v[j]; j-- {
v[j], v[j-1] = v[j-1], v[j]
}
v[i+1] = key
}
}

Expand Down
107 changes: 107 additions & 0 deletions differ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"reflect"
"sort"
"strings"
"testing"
)
Expand Down Expand Up @@ -154,3 +155,109 @@ func runTestCase(t *testing.T, tc testcase, pc patchGetter, opts ...Option) {
}
}
}

func Benchmark_sortStrings(b *testing.B) {
for _, v := range [][]string{
// 5
{
"medieval",
"bike",
"trust",
"sodium",
"hemisphere",
},
// 10
{
"general",
"lamp",
"journal",
"common",
"grind",
"hay",
"dismiss",
"sunrise",
"shoulder",
"certain",
},
// 15
{
"plant",
"instinct",
"infect",
"transaction",
"transport",
"beer",
"printer",
"neutral",
"collect",
"message",
"chaos",
"dynamic",
"justice",
"master",
"want",
},
// 20
{
"absorption",
"ditch",
"gradual",
"leftovers",
"lace",
"clash",
"fun",
"stereotype",
"lamp",
"deter",
"circle",
"lay",
"murder",
"grimace",
"jacket",
"have",
"ambiguous",
"pit",
"plug",
"notice",
},
// 25
{
"flesh",
"kidney",
"hard",
"carbon",
"ignorant",
"pocket",
"strategic",
"allow",
"advance",
"impulse",
"infinite",
"integrated",
"expenditure",
"technology",
"prevent",
"valid",
"revive",
"manager",
"sheep",
"kitchen",
"guest",
"dismissal",
"divide",
"bow",
"buffet",
},
} {
b.Run(fmt.Sprintf("sort.Strings-%d", len(v)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
sort.Strings(v)
}
})
b.Run(fmt.Sprintf("sortStrings-%d", len(v)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
sortStrings(v)
}
})
}
}

0 comments on commit d28c8f7

Please sign in to comment.