|
|
@@ -0,0 +1,151 @@ |
|
|
package gheap |
|
|
|
|
|
import ( |
|
|
"container/heap" |
|
|
"fmt" |
|
|
"math/rand" |
|
|
"testing" |
|
|
) |
|
|
|
|
|
const N = 10000000 |
|
|
|
|
|
var ints []int |
|
|
var out1, out2 []int |
|
|
|
|
|
func init() { |
|
|
for i := 0; i < N; i++ { |
|
|
ints = append(ints, rand.Int()) |
|
|
} |
|
|
out1 = make([]int, N) |
|
|
out2 = make([]int, N) |
|
|
} |
|
|
|
|
|
func UseTypeAssertion(n int) { |
|
|
mh := myHeap(make([]int, 0, n)) |
|
|
h := &mh |
|
|
|
|
|
a, b := n/2, n/4 |
|
|
c := a + b |
|
|
|
|
|
for i := 0; i < a; i++ { |
|
|
heap.Push(h, ints[i]) |
|
|
} |
|
|
for i := 0; i < b; i++ { |
|
|
out1[i] = heap.Pop(h).(int) |
|
|
} |
|
|
for i := a; i < c; i++ { |
|
|
heap.Push(h, ints[i]) |
|
|
} |
|
|
for i := b; i < a; i++ { |
|
|
out1[i] = heap.Pop(h).(int) |
|
|
} |
|
|
for i := c; i < n; i++ { |
|
|
heap.Push(h, ints[i]) |
|
|
} |
|
|
for i := a; i < n; i++ { |
|
|
out1[i] = heap.Pop(h).(int) |
|
|
} |
|
|
} |
|
|
|
|
|
func NotUseTypeAssertion(n int) { |
|
|
mh := myGHeap(make([]int, 0, n)) |
|
|
h := &mh |
|
|
|
|
|
a, b := n/2, n/4 |
|
|
c := a + b |
|
|
|
|
|
for i := 0; i < a; i++ { |
|
|
h.Push(ints[i]) |
|
|
} |
|
|
for i := 0; i < b; i++ { |
|
|
out2[i] = h.Pop() |
|
|
} |
|
|
for i := a; i < c; i++ { |
|
|
h.Push(ints[i]) |
|
|
} |
|
|
for i := b; i < a; i++ { |
|
|
out2[i] = h.Pop() |
|
|
} |
|
|
for i := c; i < n; i++ { |
|
|
h.Push(ints[i]) |
|
|
} |
|
|
for i := a; i < n; i++ { |
|
|
out2[i] = h.Pop() |
|
|
} |
|
|
} |
|
|
|
|
|
func areEq(n int) bool { |
|
|
for i := 0; i < n; i++ { |
|
|
if out1[i] != out2[i] { |
|
|
fmt.Println("mismatch!") |
|
|
return false |
|
|
} |
|
|
} |
|
|
return true |
|
|
} |
|
|
|
|
|
func benchmark(f func(int), n int, b *testing.B) { |
|
|
for i := 0; i < b.N; i++ { |
|
|
f(n) |
|
|
} |
|
|
} |
|
|
|
|
|
func BenchmarkStdHeap1000(b *testing.B) { benchmark(UseTypeAssertion, 1000, b) } |
|
|
func BenchmarkMyGHeap1000(b *testing.B) { benchmark(NotUseTypeAssertion, 1000, b) } |
|
|
func BenchmarkCheckEq1000(b *testing.B) { areEq(1000) } |
|
|
func BenchmarkStdHeap10000(b *testing.B) { benchmark(UseTypeAssertion, 10000, b) } |
|
|
func BenchmarkMyGHeap10000(b *testing.B) { benchmark(NotUseTypeAssertion, 10000, b) } |
|
|
func BenchmarkCheckEq10000(b *testing.B) { areEq(10000) } |
|
|
func BenchmarkStdHeap100000(b *testing.B) { benchmark(UseTypeAssertion, 100000, b) } |
|
|
func BenchmarkMyGHeap100000(b *testing.B) { benchmark(NotUseTypeAssertion, 100000, b) } |
|
|
func BenchmarkCheckEq100000(b *testing.B) { areEq(100000) } |
|
|
func BenchmarkStdHeap1000000(b *testing.B) { benchmark(UseTypeAssertion, 1000000, b) } |
|
|
func BenchmarkMyGHeap1000000(b *testing.B) { benchmark(NotUseTypeAssertion, 1000000, b) } |
|
|
func BenchmarkCheckEq1000000(b *testing.B) { areEq(1000000) } |
|
|
func BenchmarkStdHeap10000000(b *testing.B) { benchmark(UseTypeAssertion, 10000000, b) } |
|
|
func BenchmarkMyGHeap10000000(b *testing.B) { benchmark(NotUseTypeAssertion, 10000000, b) } |
|
|
func BenchmarkCheckEq10000000(b *testing.B) { areEq(10000000) } |
|
|
|
|
|
// for without type assertion version |
|
|
type myGHeap []int |
|
|
|
|
|
func (h *myGHeap) Less(i, j int) bool { |
|
|
return (*h)[i] < (*h)[j] |
|
|
} |
|
|
func (h *myGHeap) Swap(i, j int) { |
|
|
(*h)[i], (*h)[j] = (*h)[j], (*h)[i] |
|
|
} |
|
|
func (h *myGHeap) Len() int { |
|
|
return len(*h) |
|
|
} |
|
|
func (h *myGHeap) Pop() (v int) { |
|
|
//~ gheap.Pop(h) |
|
|
Pop(h) |
|
|
*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1] |
|
|
return |
|
|
} |
|
|
func (h *myGHeap) Push(v int) { |
|
|
*h = append(*h, v) |
|
|
//~ gheap.Push(h) |
|
|
Push(h) |
|
|
} |
|
|
|
|
|
// for type assertion version |
|
|
type myHeap []int |
|
|
|
|
|
func (h *myHeap) Less(i, j int) bool { |
|
|
return (*h)[i] < (*h)[j] |
|
|
} |
|
|
func (h *myHeap) Swap(i, j int) { |
|
|
(*h)[i], (*h)[j] = (*h)[j], (*h)[i] |
|
|
} |
|
|
func (h *myHeap) Len() int { |
|
|
return len(*h) |
|
|
} |
|
|
func (h *myHeap) Pop() (v interface{}) { |
|
|
*h, v = (*h)[:h.Len()-1], (*h)[h.Len()-1] |
|
|
return |
|
|
} |
|
|
func (h *myHeap) Push(v interface{}) { |
|
|
*h = append(*h, v.(int)) |
|
|
} |