package main

import "testing"

const N = 1615119
// It is strange that if N is large enough,
// the one line implementations are fast as the others.
// And if N is odd number, the InsertOneline_Disassemble
// implementation is about 10% faster than the others.

func init() {
    println("==================== N =", N)
}

func InsertOneline(s []int, k int, vs ...int) []int {
    return append(s[:k], append(vs, s[k:]...)...)
}

func InsertOneline_Disassemble(s []int, k int, vs ...int) []int {
    z := append(vs, s[k:]...)
    return append(s[:k], z...)
}

func InsertVerbose(s []int, k int, vs ...int) []int {
    if n := len(s) + len(vs); n <= cap(s) {
        s2 := s[:n]
        copy(s2[k+len(vs):], s[k:])
        copy(s2[k:], vs)
        return s2
    }
    s2 := make([]int, len(s) + len(vs))
    copy(s2, s[:k])
    copy(s2[k:], vs)
    copy(s2[k+len(vs):], s[k:])
    return s2
}


func InsertVerbose_b(s []int, k int, vs ...int) []int {
    if n := len(s) + len(vs); n <= cap(s) {
        s2 := s[:n]
        copy(s2[k+len(vs):], s[k:])
        copy(s2[k:], vs)
        return s2
    }
    s2 := make([]int, 0, len(s) + len(vs))
    s2 = append(s2, s[:k]...)
    s2 = append(s2, vs...)
    s2 = append(s2, s[k:]...)
    return s2
}

func InsertVerbose_c(s []int, k int, vs ...int) []int {
    if n := len(s) + len(vs); n <= cap(s) {
        s2 := s[:n]
        copy(s2[k+len(vs):], s[k:])
        copy(s2[k:], vs)
        return s2
    }
    s2 := append([]int(nil), make([]int, len(s) + len(vs))...)[:0]
    s2 = append(s2, s[:k]...)
    s2 = append(s2, vs...)
    s2 = append(s2, s[k:]...)
    return s2
}

var s1 []int
func Benchmark_InsertOneline(b *testing.B) {
    var x = make([]int, N)
    var y = make([]int, N/2)
    var k = N/5
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        s1 = InsertOneline(x, k, y...)
    }
}

var s1b []int
func Benchmark_InsertOneline_Disassemble(b *testing.B) {
    var x = make([]int, N)
    var y = make([]int, N/2)
    var k = N/2
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        s1b = InsertOneline_Disassemble(x, k, y...)
    }
}

var s2 []int
func Benchmark_InsertVerbose(b *testing.B) {
    var x = make([]int, N)
    var y = make([]int, N/2)
    var k = N/2
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        s2 = InsertVerbose(x, k, y...)
    }
}

var s3 []int
func Benchmark_InsertVerbose_b(b *testing.B) {
    var x = make([]int, N)
    var y = make([]int, N/2)
    var k = N/2
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        s3 = InsertVerbose_b(x, k, y...)
    }
}

var s4 []int
func Benchmark_InsertVerbose_c(b *testing.B) {
    var x = make([]int, N)
    var y = make([]int, N/2)
    var k = N/2
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        s4 = InsertVerbose_c(x, k, y...)
    }
}


The result:

$ go test -bench=. -benchtime=3s
==================== N = 1615119
goos: linux
goarch: amd64
pkg: a.y/bench/sliceinsert
cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
Benchmark_InsertOneline-4                        693       4741509 ns/op
Benchmark_InsertOneline_Disassemble-4            871       4194142 ns/op
Benchmark_InsertVerbose-4                        764       4627334 ns/op
Benchmark_InsertVerbose_b-4                      769       4958537 ns/op
Benchmark_InsertVerbose_c-4                      661       4855514 ns/op

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a6c251ac-02dd-40f6-895d-aa55e11a55c6n%40googlegroups.com.

Reply via email to