为了账号安全,请及时绑定邮箱和手机立即绑定

在golang中连接多个切片

在golang中连接多个切片

Go
四季花海 2022-01-17 18:34:33
我正在尝试合并多个切片,如下所示,package routesimport (    "net/http")type Route struct {    Name        string    Method      string    Pattern     string    Secured     bool    HandlerFunc http.HandlerFunc}type Routes []Routevar ApplicationRoutes Routesfunc init() {    ApplicationRoutes = append(        WifiUserRoutes,        WifiUsageRoutes,        WifiLocationRoutes,        DashboardUserRoutes,        DashoardAppRoutes,        RadiusRoutes,        AuthenticationRoutes...    )}然而,内置的 append() 能够附加两个切片,因此它会在编译时抛出太多参数来附加。是否有替代功能来完成任务?还是有更好的方法来合并切片?
查看完整描述

2 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

这个问题已经回答了,但我想在这里发布这个问题,因为接受的答案不是最有效的。


原因是创建一个空切片然后追加可能会导致许多不必要的分配。


最有效的方法是预先分配一个切片并将元素复制到其中。下面是一个以两种方式实现连接的包。如果您进行基准测试,您会发现预分配速度快了约 2 倍,并且分配的内存要少得多。


基准测试结果:


go test . -bench=. -benchmem

testing: warning: no tests to run

BenchmarkConcatCopyPreAllocate-8    30000000            47.9 ns/op        64 B/op          1 allocs/op

BenchmarkConcatAppend-8             20000000           107 ns/op         112 B/op          3 allocs/op

包连接:


package concat


func concatCopyPreAllocate(slices [][]byte) []byte {

    var totalLen int

    for _, s := range slices {

        totalLen += len(s)

    }

    tmp := make([]byte, totalLen)

    var i int

    for _, s := range slices {

        i += copy(tmp[i:], s)

    }

    return tmp

}


func concatAppend(slices [][]byte) []byte {

    var tmp []byte

    for _, s := range slices {

        tmp = append(tmp, s...)

    }

    return tmp

}

基准测试:


package concat


import "testing"


var slices = [][]byte{

    []byte("my first slice"),

    []byte("second slice"),

    []byte("third slice"),

    []byte("fourth slice"),

    []byte("fifth slice"),

}


var B []byte


func BenchmarkConcatCopyPreAllocate(b *testing.B) {

    for n := 0; n < b.N; n++ {

        B = concatCopyPreAllocate(slices)

    }

}


func BenchmarkConcatAppend(b *testing.B) {

    for n := 0; n < b.N; n++ {

        B = concatAppend(slices)

    }

}


查看完整回答
反对 回复 2022-01-17
?
梦里花落0921

TA贡献1772条经验 获得超6个赞

append对单个元素进行操作,而不是对整个切片进行操作。将每个切片附加到循环中


routes := []Routes{

    WifiUserRoutes,

    WifiUsageRoutes,

    WifiLocationRoutes,

    DashboardUserRoutes,

    DashoardAppRoutes,

    RadiusRoutes,

    AuthenticationRoutes,

}


var ApplicationRoutes []Route

for _, r := range routes {

    ApplicationRoutes = append(ApplicationRoutes, r...)

}


查看完整回答
反对 回复 2022-01-17
  • 2 回答
  • 0 关注
  • 433 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信