Questa sezione fornisce linee guida per la codifica prospettate dal punto di vista dello sviluppo Golang, che sono utili per migliorare le performance.
Preferisci strconv rispetto a fmt
Quando si convertono tipi primitivi in stringhe o viceversa, strconv
è più veloce rispetto a fmt
.
Non raccomandato:
for i := 0; i < b.N; i++ {
s := fmt.Sprint(rand.Int())
}
Raccomandato:
for i := 0; i < b.N; i++ {
s := strconv.Itoa(rand.Int())
}
Evita di convertire le stringhe in byte
Evita di creare ripetutamente una slice di byte da una stringa fissa. Invece, esegui la conversione una volta e cattura il risultato.
Non raccomandato:
for i := 0; i < b.N; i++ {
w.Write([]byte("Hello world"))
}
Raccomandato:
data := []byte("Hello world")
for i := 0; i < b.N; i++ {
w.Write(data)
}
Specifica la capacità del contenitore
Specifica la capacità del contenitore, se possibile, per pre-allocare memoria per il contenitore. Ciò minimizza le successive allocazioni (copiatura e ridimensionamento del contenitore) durante l'aggiunta di elementi.
Suggerimento per la capacità della mappa
Nella maggior parte dei casi, fornire informazioni sulla capacità durante l'inizializzazione con make()
.
make(map[T1]T2, suggerimento)
Fornire un suggerimento di capacità a make()
cercherà di ridimensionare la mappa all'inizializzazione, riducendo la riallocazione di memoria durante l'aggiunta di elementi alla mappa.
Si noti che, a differenza delle slice, un suggerimento di capacità della mappa non garantisce una preallocazione completa, ma viene utilizzato per stimare il numero di secchi della hashmap richiesti. Pertanto, l'allocazione potrebbe comunque verificarsi durante l'aggiunta di elementi alla mappa, anche quando viene specificata la capacità della mappa.
Non raccomandato:
m := make(map[string]os.FileInfo)
files, _ := os.ReadDir("./files")
for _, f := range files {
m[f.Name()] = f
}
// m è creato senza suggerimento di dimensione; potrebbero verificarsi più allocazioni in fase di esecuzione.
Raccomandato:
files, _ := os.ReadDir("./files")
m := make(map[string]os.FileInfo, len(files))
for _, f := range files {
m[f.Name()] = f
}
// m è creato con un suggerimento di dimensione; potrebbero verificarsi meno allocazioni in fase di esecuzione.
Specifica la capacità della slice
Nella maggior parte dei casi, fornire informazioni sulla capacità durante l'inizializzazione di una slice con make()
, specialmente durante l'aggiunta alla slice.
make([]T, lunghezza, capacità)
A differenza delle mappe, la capacità di una slice non è solo un suggerimento: il compilatore assegnerà abbastanza memoria per la capacità della slice fornita in make()
, il che significa che le successive operazioni di append()
risulteranno in zero allocazioni (fino a quando la lunghezza della slice non corrisponde alla sua capacità, dopo di che qualsiasi aggiunta potrebbe ridimensionare per ospitare elementi aggiuntivi).
Non raccomandato:
for n := 0; n < b.N; n++ {
data := make([]int, 0)
for k := 0; k < size; k++{
data = append(data, k)
}
}
Raccomandato:
for n := 0; n < b.N; n++ {
data := make([]int, 0, size)
for k := 0; k < size; k++{
data = append(data, k)
}
}