首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在预先分配的片上追加比索引更快?

问为什么在预先分配的片上追加比索引更快?
EN

Stack Overflow用户
提问于 2017-11-05 17:25:18
回答 1查看 494关注 0票数 3

我编写了以下Go基准测试(Go1.9.2,Linux amd64)来测试索引和附加索引:

代码语言:javascript
复制
func BenchmarkIndex(b *testing.B) {
    for i := 0; i < b.N; i++ {
        existing := make([]int64, 1000, 1000)
        init := make([]int64, 1000) // len 1000, cap 1000
        for index, element := range existing {
            init[index] = element
        }
    }
}

func BenchmarkAppend(b *testing.B) {
    for i := 0; i < b.N; i++ {
        existing := make([]int64, 1000, 1000)
        init := make([]int64, 0, 1000) // len 0, capacity 1000
        for _, element := range existing {
            init = append(init, element)
        }
    }
}

并得到以下结果:

代码语言:javascript
复制
goos: linux
goarch: amd64
BenchmarkIndex-4         1000000          2183 ns/op
BenchmarkAppend-4        1000000          1933 ns/op
PASS

我有点搞不懂为什么append的表现似乎比索引到片中要好。它与省略范围内的index有关吗?如果不是的话,在引擎盖下面附加什么可以使它比索引更快?

供参考,这里是附加的来源。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-05 18:15:27

在第一计算机上:

代码语言:javascript
复制
$ go test same_test.go -run=! -bench=. -benchmem -count=3
goos: linux
goarch: amd64
BenchmarkIndex-4     1000000    1290 ns/op    0 B/op    0 allocs/op
BenchmarkIndex-4     1000000    1290 ns/op    0 B/op    0 allocs/op
BenchmarkIndex-4     1000000    1288 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-4    1000000    1299 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-4    1000000    1302 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-4    1000000    1301 ns/op    0 B/op    0 allocs/op
PASS
ok      command-line-arguments  7.868s
$ go version
go version devel +38c725b148 Sun Nov 5 17:30:11 2017 +0000 linux/amd64
$ 

BenchmarkAppend和BenchmarkIndex的区别是:

代码语言:javascript
复制
((1299+1302+1301) - (1290+1290+1288)) * 100 / (1290+1290+1288) =  +0.879%

他们是一样的。

在第二计算机上:

代码语言:javascript
复制
$ go test same_test.go -run=! -bench=. -benchmem -count=3
goos: linux
goarch: amd64
BenchmarkIndex-8     2000000    706 ns/op    0 B/op    0 allocs/op
BenchmarkIndex-8     2000000    713 ns/op    0 B/op    0 allocs/op
BenchmarkIndex-8     2000000    710 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-8    2000000    711 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-8    2000000    718 ns/op    0 B/op    0 allocs/op
BenchmarkAppend-8    2000000    718 ns/op    0 B/op    0 allocs/op
PASS
ok      command-line-arguments  12.945s
$ go version
go version devel +38c725b148 Sun Nov 5 17:30:11 2017 +0000 linux/amd64
$ 

BenchmarkAppend和BenchmarkIndex的区别是:

代码语言:javascript
复制
((711+718+718) - (706+713+710)) * 100 / (706+713+710) =  +0.845%

他们是一样的。

让我们一次测量一件事,索引与追加在预先分配的片上,这避免了诸如内存管理之类的混淆问题。

代码语言:javascript
复制
package main

import "testing"

func BenchmarkIndexing(b *testing.B) {
    existing := make([]int64, 1000, 1000)
    init := make([]int64, 1000) // len 1000, cap 1000
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        init = init[:cap(init)]
        for index, element := range existing {
            init[index] = element
        }
    }
}

func BenchmarkAppending(b *testing.B) {
    existing := make([]int64, 1000, 1000)
    init := make([]int64, 0, 1000) // len 0, capacity 1000
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        init = init[:0]
        for _, element := range existing {
            init = append(init, element)
        }
    }
}

输出:

代码语言:javascript
复制
$ go test same_test.go -run=! -bench=ing -benchmem -count=3
goos: linux
goarch: amd64
BenchmarkIndexing-4     2000000    736 ns/op    0 B/op    0 allocs/op
BenchmarkIndexing-4     2000000    735 ns/op    0 B/op    0 allocs/op
BenchmarkIndexing-4     2000000    735 ns/op    0 B/op    0 allocs/op
BenchmarkAppending-4    2000000    733 ns/op    0 B/op    0 allocs/op
BenchmarkAppending-4    2000000    733 ns/op    0 B/op    0 allocs/op
BenchmarkAppending-4    2000000    733 ns/op    0 B/op    0 allocs/op
PASS
ok      command-line-arguments  13.303s
$ go version
go version devel +38c725b148 Sun Nov 5 17:30:11 2017 +0000 linux/amd64
$

BenchmarkAppend和BenchmarkIndex的区别是:

代码语言:javascript
复制
((733+733+733) - (736+735+735)) * 100 / (736+735+735) =  −0.317%

他们是一样的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47124412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档