Skip to content

Instantly share code, notes, and snippets.

@imran31415
Created November 20, 2019 22:42
Show Gist options
  • Save imran31415/38e2ac690e2fadab6f7fd88b7ecd4a42 to your computer and use it in GitHub Desktop.
Save imran31415/38e2ac690e2fadab6f7fd88b7ecd4a42 to your computer and use it in GitHub Desktop.
package bench
import (
"testing"
)
type Item struct {
Position int
name string
IsPin bool
}
func promotePins(in []*Item) []*Item {
for index := len(in) - 1; index >= 0; index-- {
item := in[index]
if !item.IsPin {
continue
}
p := int(item.Position)
// We only move pinned items if they are at an index higher than they should be
if index < p {
insert := p
// If the insert positon is greater than the number of items then insert to last position
if p > len(in) {
insert = len(in) - 1
}
// shift fwd all elements up to pin position, by one
// ex. 1,2,5,3,4,6 -> 1,2,3,4,4,6 -> 1,2,3,4,5,6
copy(in[index:], in[index+1:insert+1])
in[insert] = item
}
}
return in
}
func orderPins(in []*Item) []*Item {
pinItems := make([]*Item, 0, len(in))
feedItems := make([]*Item, 0, len(in))
for _, i := range in {
if i.IsPin {
pinItems = append(pinItems, i)
} else {
feedItems = append(feedItems, i)
}
}
// insert pins at correct position
for _, p := range pinItems {
if p.Position < len(feedItems) {
feedItems = insert(feedItems, p.Position, p)
} else {
feedItems = append(feedItems, p)
}
}
return feedItems
}
func insert(s []*Item, at int, val *Item) []*Item {
// Make sure there is enough room
if s == nil {
return s
}
// Move all elements of s up one slot
copy(s[at+1:], s[at:])
// Insert the new element at the now free position
s[at] = val
return s
}
func BenchmarkPromotePins10000(b *testing.B) {
items := []*Item{
&Item{
IsPin: true,
name: "IAMAPIN",
Position: 2,
},
&Item{
name: "blah1",
},
&Item{
name: "blah2",
},
&Item{
name: "blah3",
},
&Item{
name: "blah4",
},
&Item{
name: "blah5",
},
&Item{
name: "blah6",
},
&Item{
name: "blah7",
},
&Item{
name: "blah8",
},
&Item{
name: "blah9",
},
&Item{
name: "blah10",
},
&Item{
name: "blah11",
},
&Item{
name: "blah12",
},
&Item{
name: "blah13",
},
&Item{
name: "blah14",
},
&Item{
name: "blah15",
},
&Item{
name: "blah16",
},
&Item{
name: "blah17",
},
&Item{
name: "blah18",
},
&Item{
name: "blah19",
},
&Item{
name: "blah12",
},
}
// run the pin sort function b.N times
for n := 0; n < b.N; n++ {
promotePins(items)
}
}
@imran31415
Copy link
Author

imran31415 commented Nov 20, 2019

swap the promotePins function call for orderPins and re-run benchmark to see the difference.

@negator
Copy link

negator commented Nov 21, 2019

Fyi, you can just create a second Benchmark function, reuse the data, and invoke the other algorithm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment