Optimize merging/sorting
Previously we sorted a list e.g. [3,2,1] that we already got, then fetched another list e.g. [6,7,8,2]. Instead of just sorting the new list and manually merging it we would sort the appended lists: [1,2,3, 6,7,8,2] Despite mergesort, this is now optimized in a two-step process: * ONLY sort the new list * call a Merge function on both lists, that assumes sorted and deduplicated lists This should be faster.
This commit is contained in:
parent
17aa010ebf
commit
ebbcd71b3d
@ -129,13 +129,14 @@ func numbersHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// sort fallthrough, either the inputChan is currently "empty"
|
||||
// or we fetched all URLs already
|
||||
go func(n []int) {
|
||||
res, err := sort.SortedAndDedup(ctx, n)
|
||||
go func(sorted []int, unsorted_buffer []int) {
|
||||
res, err := sort.SortedAndDedup(ctx, unsorted_buffer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sortChan <- res
|
||||
}(append(sortedNumbers, numberBuffer...))
|
||||
merged := sort.MergeLists(sortedNumbers, res)
|
||||
sortChan <- merged
|
||||
}(sortedNumbers, numberBuffer)
|
||||
numberBuffer = []int{}
|
||||
|
||||
select {
|
||||
|
@ -6,6 +6,39 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Merge too already sorted and deduplicated lists.
|
||||
func MergeLists(l []int, r []int) []int {
|
||||
n := []int{}
|
||||
|
||||
i := 0
|
||||
j := 0
|
||||
for {
|
||||
if i == len(l) && j == len(r) {
|
||||
break
|
||||
} else if i == len(l) {
|
||||
n = append(n, r[j:]...)
|
||||
break
|
||||
} else if j == len(r) {
|
||||
n = append(n, l[i:]...)
|
||||
break
|
||||
}
|
||||
|
||||
if l[i] < r[j] {
|
||||
n = append(n, l[i])
|
||||
i++
|
||||
} else if l[i] > r[j] {
|
||||
n = append(n, r[j])
|
||||
j++
|
||||
} else if l[i] == r[j] {
|
||||
n = append(n, l[i])
|
||||
i++
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// Mergesorts and deduplicates the list.
|
||||
func SortedAndDedup(ctx context.Context, list []int) (res []int, err error) {
|
||||
sorted, err := Mergesort(ctx, list)
|
||||
|
@ -5,6 +5,40 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMergeLists(t *testing.T) {
|
||||
ls := [][]int{
|
||||
{1, 3, 4, 5, 7},
|
||||
{1, 3, 4, 5, 7},
|
||||
{},
|
||||
{1, 3, 4, 5, 7},
|
||||
{},
|
||||
}
|
||||
|
||||
rs := [][]int{
|
||||
{3, 4, 6, 9},
|
||||
{},
|
||||
{1, 3, 4, 5, 7},
|
||||
{3, 5, 7},
|
||||
{},
|
||||
}
|
||||
|
||||
result := [][]int{
|
||||
{1, 3, 4, 5, 6, 7, 9},
|
||||
{1, 3, 4, 5, 7},
|
||||
{1, 3, 4, 5, 7},
|
||||
{1, 3, 4, 5, 7},
|
||||
{},
|
||||
}
|
||||
|
||||
for i := range ls {
|
||||
merge := MergeLists(ls[i], rs[i])
|
||||
if slice_equal(merge, result[i]) != true {
|
||||
t.Errorf("Failure in merging, expected %s got %s", result[i], merge)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test the mergesort and deduplication with a predefined set of slices.
|
||||
func TestSortAndDedup(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
Loading…
Reference in New Issue
Block a user