2016-06-17 8 views
10

che sto cercando di unire più sezioni come segue,CONCAT più sezioni in 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... 
    ) 
} 

Tuttavia l'accodamento integrato() è in grado di aggiungendo due fette, quindi getta troppi argomenti per aggiungere a compilare il tempo. Esiste una funzione alternativa per raggiungere l'obiettivo? o c'è un modo migliore per unire le fette?

risposta

11

append funziona su singoli elementi, non su sezioni intere. Aggiungi ogni sezione in un loop

routes := []Routes{ 
    WifiUserRoutes, 
    WifiUsageRoutes, 
    WifiLocationRoutes, 
    DashboardUserRoutes, 
    DashoardAppRoutes, 
    RadiusRoutes, 
    AuthenticationRoutes, 
} 

var ApplicationRoutes []Route 
for _, r := range routes { 
    ApplicationRoutes = append(ApplicationRoutes, r...) 
} 
9

Questa domanda ha già avuto risposta, ma ho voluto postarla qui perché la risposta accettata non è la più efficiente.

Il motivo è che la creazione di una sezione vuota e quindi l'aggiunta possono portare a molte allocazioni non necessarie.

Il modo più efficiente sarebbe pre-allocare una sezione e copiare gli elementi in essa. Di seguito è riportato un pacchetto che implementa la concatenazione in entrambe le direzioni. Se fai un benchmark puoi vedere che la pre-allocazione è ~ 2x più veloce e assegna molto meno memoria.

Risultati Benchmark: concat

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 

pacchetto:

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 
} 

test di riferimento:

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) 
    } 
}