在golang中连接多个切片

我正在尝试合并多个切片,如下所示,


package routes


import (

    "net/http"

)


type Route struct {

    Name        string

    Method      string

    Pattern     string

    Secured     bool

    HandlerFunc http.HandlerFunc

}


type Routes []Route


var ApplicationRoutes Routes


func init() {

    ApplicationRoutes = append(

        WifiUserRoutes,

        WifiUsageRoutes,

        WifiLocationRoutes,

        DashboardUserRoutes,

        DashoardAppRoutes,

        RadiusRoutes,

        AuthenticationRoutes...

    )

}

然而,内置的 append() 能够附加两个切片,因此它会在编译时抛出太多参数来附加。是否有替代功能来完成任务?还是有更好的方法来合并切片?


四季花海
浏览 434回答 2
2回答

慕标5832272

这个问题已经回答了,但我想在这里发布这个问题,因为接受的答案不是最有效的。原因是创建一个空切片然后追加可能会导致许多不必要的分配。最有效的方法是预先分配一个切片并将元素复制到其中。下面是一个以两种方式实现连接的包。如果您进行基准测试,您会发现预分配速度快了约 2 倍,并且分配的内存要少得多。基准测试结果:go test . -bench=. -benchmemtesting: warning: no tests to runBenchmarkConcatCopyPreAllocate-8&nbsp; &nbsp; 30000000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 47.9 ns/op&nbsp; &nbsp; &nbsp; &nbsp; 64 B/op&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 allocs/opBenchmarkConcatAppend-8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;20000000&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;107 ns/op&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;112 B/op&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 allocs/op包连接:package concatfunc concatCopyPreAllocate(slices [][]byte) []byte {&nbsp; &nbsp; var totalLen int&nbsp; &nbsp; for _, s := range slices {&nbsp; &nbsp; &nbsp; &nbsp; totalLen += len(s)&nbsp; &nbsp; }&nbsp; &nbsp; tmp := make([]byte, totalLen)&nbsp; &nbsp; var i int&nbsp; &nbsp; for _, s := range slices {&nbsp; &nbsp; &nbsp; &nbsp; i += copy(tmp[i:], s)&nbsp; &nbsp; }&nbsp; &nbsp; return tmp}func concatAppend(slices [][]byte) []byte {&nbsp; &nbsp; var tmp []byte&nbsp; &nbsp; for _, s := range slices {&nbsp; &nbsp; &nbsp; &nbsp; tmp = append(tmp, s...)&nbsp; &nbsp; }&nbsp; &nbsp; return tmp}基准测试:package concatimport "testing"var slices = [][]byte{&nbsp; &nbsp; []byte("my first slice"),&nbsp; &nbsp; []byte("second slice"),&nbsp; &nbsp; []byte("third slice"),&nbsp; &nbsp; []byte("fourth slice"),&nbsp; &nbsp; []byte("fifth slice"),}var B []bytefunc BenchmarkConcatCopyPreAllocate(b *testing.B) {&nbsp; &nbsp; for n := 0; n < b.N; n++ {&nbsp; &nbsp; &nbsp; &nbsp; B = concatCopyPreAllocate(slices)&nbsp; &nbsp; }}func BenchmarkConcatAppend(b *testing.B) {&nbsp; &nbsp; for n := 0; n < b.N; n++ {&nbsp; &nbsp; &nbsp; &nbsp; B = concatAppend(slices)&nbsp; &nbsp; }}

梦里花落0921

append对单个元素进行操作,而不是对整个切片进行操作。将每个切片附加到循环中routes := []Routes{&nbsp; &nbsp; WifiUserRoutes,&nbsp; &nbsp; WifiUsageRoutes,&nbsp; &nbsp; WifiLocationRoutes,&nbsp; &nbsp; DashboardUserRoutes,&nbsp; &nbsp; DashoardAppRoutes,&nbsp; &nbsp; RadiusRoutes,&nbsp; &nbsp; AuthenticationRoutes,}var ApplicationRoutes []Routefor _, r := range routes {&nbsp; &nbsp; ApplicationRoutes = append(ApplicationRoutes, r...)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go