Maison > développement back-end > Golang > À propos de l'extension de Golang Slice

À propos de l'extension de Golang Slice

藏色散人
Libérer: 2021-06-23 16:17:56
avant
1760 Les gens l'ont consulté
Chaque opération d'ajout vérifiera si la tranche a une capacité suffisante. Si cela est suffisant, les éléments seront ajoutés directement au tableau d'origine. et une nouvelle tranche sera renvoyée. Le tableau sous-jacent reste inchangé
et si la capacité n'est pas suffisante, un nouveau tableau sous-jacent avec une capacité suffisante sera créé. Les éléments du tableau précédent seront copiés en premier, puis les nouveaux éléments. sera ajouté à l'arrière, puis une nouvelle tranche sera renvoyée. Le tableau sous-jacent changera
La définition de capacité du nouveau tableau ici est d'augmenter selon le mécanisme de 乘以2

Recommandé. tutoriels associés : "tutoriel Golang"

Et aujourd'hui, j'ai vu En ce qui concerne la structure sous-jacente du découpage Golang, à savoir Reflect.SliceHeader, nous constatons que l'expansion d'append est pas exactement une multiplication par 2. Le code source est le suivant (Go version 1.13) :

// grow grows the slice s so that it can hold extra more values, allocating
// more capacity if needed. It also returns the old and new slice lengths.
func grow(s Value, extra int) (Value, int, int) {
    i0 := s.Len()
    i1 := i0 + extra
    if i1 < i0 {
        panic("reflect.Append: slice overflow")
    }
    m := s.Cap()
    if i1 <= m {
        return s.Slice(0, i1), i0, i1
    }
    if m == 0 {
        m = extra
    } else {
        for m < i1 {
            if i0 < 1024 {
                m += m
            } else {
                m += m / 4
            }
        }
    }
    t := MakeSlice(s.Type(), i1, m)
    Copy(t, s)
    return t, i0, i1
}

// Append appends the values x to a slice s and returns the resulting slice.
// As in Go, each x's value must be assignable to the slice's element type.
func Append(s Value, x ...Value) Value {
    s.mustBe(Slice)
    s, i0, i1 := grow(s, len(x))
    for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
        s.Index(i).Set(x[j])
    }
    return s
}
Copier après la connexion

First Append détermine si le type est slice, puis appelle grow Expansion, à partir du jugement de l1 <= m, nous pouvons constater que lorsque la capacité est effectivement suffisante, nous créons simplement une nouvelle tranche

pour le tableau d'origine. Mais lorsque la capacité est insuffisante, nous ne pouvons le voir que lorsque l'élément actuel i0 est inférieur à. 1024 Lorsque la vitesse est 2 fois, c'est normal. Sinon, elle n'augmente que de 25% à chaque fois. La vérification du code est la suivante :

func main() {
    str := make([]int, 1023)
    fmt.Println(len(str), cap(str))
    str = append(str, 1)
    fmt.Println(len(str), cap(str))
    str = append(str, 1)
    fmt.Println(len(str), cap(str))
}

输出:
1023 1023
1024 2048
1025 2048
Copier après la connexion

Après que la capacité initiale ait atteint 1024, elle n'a augmenté que de 256.

func main() {
    str := make([]int, 1024)
    fmt.Println(len(str), cap(str))
    str = append(str, 1)
    fmt.Println(len(str), cap(str))
    str = append(str, 1)
    fmt.Println(len(str), cap(str))
}
输出:
1024 1024
1025 1280
1026 1280
Copier après la connexion

Bien sûr ici Une autre confusion est que lorsque la capacité initiale est de 1023, ce n'est pas 1023×2, mais directement 1024×2. Lors du test de l'extension initiale 500, c'est aussi directement 512×2. est supposé que le niveau inférieur sera toujours complété à 2 lors de l'ajustement dynamique nième puissance, actuellement nous ne voyons que la définition de l'ajout sous le package intégré, et nous devons continuer à explorer

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal