Gehen tut haben keine wirkliche Möglichkeit zu schrumpfen Scheibe? Ist das ein Problem?
Ich habe versucht, Gehen für einige Zeit, und diese Frage hält mich nervt. Sagen wir ich Baue ein etwas großes dataset in eine Scheibe (sagen wir, 10 Millionen int64s).
package main
import (
"math"
"fmt"
)
func main() {
var a []int64
var i int64;
upto := int64(math.Pow10(7))
for i = 0; i < upto; i++ {
a = append(a, i)
}
fmt.Println(cap(a))
}
Aber dann habe ich entscheiden, dass ich nicht wollen, dass die meisten von Ihnen, so will ich bis zum Ende mit einer Scheibe nur 10 von denen. Ich habe versucht, sowohl das schneiden und löschen von Techniken, die auf Go ' s wiki aber keiner von Ihnen scheinen zur Verringerung der slice-Fähigkeit.
Also das ist meine Frage: Gehen tut hat keine wirkliche Möglichkeit, schrumpft die Kapazität von einer Scheibe, die ähnlich realloc()
-ing mit einer kleineren Größe als argument in Ihren vorherigen Anruf auf den gleichen Zeiger in C? Ist das ein Problem und wie sollte man damit umgehen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Durchführen, in der Tat, ein realloc von einem slice:
Wenn es funktioniert eine Kopie der
newSize
Elemente zu einem neuen Speicher-Ort, oder wenn Sie eine tatsächliche im Ort Größe wie in realloc(3) ist im vollständigen Ermessen des Compilers. Sie möglicherweise wollen untersuchen, den aktuellen Stand und vielleicht heben Sie ein Problem, wenn es Raum für Verbesserungen in diesem.Dies ist jedoch wahrscheinlich eine Mikro-Optimierung. Die erste Quelle von performance-Verbesserungen, liegt fast immer in der Auswahl eines besseren Algorithmus und/oder eine bessere Datenstruktur. Mithilfe eine enorm große Vektor-schließlich halten Sie ein paar Elemente, die nur ist wahrscheinlich nicht die beste option wrt Speicherverbrauch.
EDIT: Das oben ist nur teilweise richtig. Der compiler nicht, im Allgemeinen Fall herleiten, wenn es andere Hinweise auf die Scheibe background-array. So ist die realloc ist nicht anwendbar. Das obige snippet ist eigentlich garantiert zu Registrierungsvorgang eine Kopie von "newSize" - Elementen. Sorry für jede Verwirrung, die möglicherweise erstellt wurden.
Gehen nicht über eine Möglichkeit der schrumpfenden Scheiben schneiden. Dies ist nicht ein problem in den meisten Fällen, aber wenn Sie Profil-Ihr Gedächtnis verwenden und finden, Sie sind mit zu viel, Sie können etwas dagegen tun:
Erstens, können Sie einfach erstellen Sie ein Segment von der Größe, die Sie benötigen, und kopieren Sie Ihre Daten in Sie. Der garbage collector wird dann frei die große Scheibe. Kopieren built-in
Zweitens, können Sie re-verwenden Sie die große Scheibe jedes mal, wenn Sie wollen, zu generieren, so dass Sie nie reservieren, es mehr als einmal.
Auf eine Letzte Anmerkung, die Sie verwenden können
1e7
stattmath.Pow10(7)
.copy
istcopy(dst, src)
, nichtcopy(src, dst)
Darüber hinaus können Sie Ihr re-use-die meisten von den zugewiesenen Speicher während der Arbeit von Ihnen-app, werfen Sie einen Blick auf: bufs-Paket
PS, wenn Sie re-alocate neuen Speicher für kleinere Scheibe, alte Speicher kann nicht freigegeben werden, in der gleichen Zeit, es wird freigegeben, wenn der garbage collector entscheidet.
Lassen Sie uns sehen Sie dieses Beispiel:
Es produziert die folgende Ausgabe:
s
ist eine Scheibe, die hält 8 Stücke von Zeichenfolgen.t
ist eine Scheibe, die hält das Teil[C D]
. Die Länge dert
2 ist, aber da es verwendet die gleichen verborgenen array vons
, seine Kapazität ist 6 (von "C" bis "H"). Die Frage ist: wie haben ein Stück von[C D]
, das unabhängig von dem der hidden-array vons
? Erstellen Sie einfach eine neue Scheibe von strings mit Länge 2 (sliceu
) und kopieren Sie den Inhaltt
zuu
.u
's zugrunde liegenden versteckten array unterscheidet sich von der versteckten Reihe vons
.Anfängliche problem war dies: Sie haben eine große Scheibe und legen Sie eine neue kleinere Scheibe drauf. Da die kleineren Scheibe verwendet den gleichen hidden-array, der garbage collector wird nicht löschen Sie die versteckte array.
Siehe Ende von diesem post für mehr info: http://blog.golang.org/go-slices-usage-and-internals .