PHP-Editor Zimo ist hier, um eine häufig gestellte Frage zu beantworten: „Was ist der effektivste Weg, Byte-Dateien in int64-Slices einzulesen?“ Wenn wir Byte-Dateien in int64-Slices einlesen müssen, können wir den folgenden Ansatz verwenden: Verwenden Sie zunächst die Funktion file_get_contents, um die Byte-Datei zu lesen, und entpacken Sie die Byte-Datei dann mit der Funktion unpack in int64-Slices. Diese Methode ist einfach und effizient und kann Byte-Dateien schnell in int64-Slices konvertieren, um unseren Anforderungen gerecht zu werden. Ich hoffe, diese Methode kann allen helfen!
Ich habe mehrere gepackte int64-Dateien. Ich brauche sie als int64-Slices im Speicher. Das Problem besteht darin, dass die Dateien zusammengenommen mehr als die Hälfte des Arbeitsspeichers der Maschine ausmachen, sodass der Speicherplatz begrenzt ist. Standardoptionen in Go sehen so aus:
a := make([]int64, f.Size()/8) binary.Read(f, binary.LittleEndian, a)
Leider binary
包将立即分配一个大小为 f.size()*8
的 []byte
und der Speicher geht aus.
Es funktioniert zwar, wenn ich jedes Byte einzeln lese und in das Slice kopiere, aber das ist zu langsam.
Die ideale Situation wäre, []byte
直接转换为 []int64
zu verwenden und dem Compiler einfach zu sagen: „OK, das sind jetzt ganze Zahlen“, aber das funktioniert offensichtlich nicht. Gibt es eine Möglichkeit, etwas Ähnliches zu erreichen? Verwenden Sie möglicherweise ein unsicheres Paket oder fügen Sie c ein, wenn dies unbedingt erforderlich ist?
Ich habe mehrere gepackte int64-Dateien. Ich brauche sie als int64-Slices im Speicher. Das Problem besteht darin, dass die Dateien zusammengenommen mehr als die Hälfte des Arbeitsspeichers der Maschine ausmachen, sodass der Speicherplatz begrenzt ist.
Die Standardoptionen in Go sehen folgendermaßen aus:
a := make([]int64, f.size()/8) binary.read(f, binary.littleendian, a)
Leider weist das Binärpaket sofort ein []Byte der Größe f.size()*8 zu und es ist nicht mehr genügend Speicher vorhanden.
Alle Funktionen beanspruchen nur minimalen Speicher.
// same endian architecture and data // most efficient (no data conversion). func readfileint64se(filename string) ([]int64, error) { b, err := os.readfile(filename) if err != nil { return nil, err } const i64size = int(unsafe.sizeof(int64(0))) i64ptr := (*int64)(unsafe.pointer(unsafe.slicedata(b))) i64len := len(b) / i64size i64 := unsafe.slice(i64ptr, i64len) return i64, nil }
Für eine amd64-Architektur (Littleendian) und maximale Effizienz mit Littleendian-Daten (keine Datenkonvertierung erforderlich) verwenden Sie beispielsweise readfileint64se
.
Byte-Reihenfolge-Irrtum – Raub Pike
https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
// littleendian in-place data conversion for any architecture func readfileint64le(filename string) ([]int64, error) { b, err := os.readfile(filename) if err != nil { return nil, err } const i64size = int(unsafe.sizeof(int64(0))) i64ptr := (*int64)(unsafe.pointer(unsafe.slicedata(b))) i64len := len(b) / i64size i64 := unsafe.slice(i64ptr, i64len) for i, j := i64size, 0; i <= len(b); i, j = i+i64size, j+1 { i64[j] = int64(binary.littleendian.uint64(b[i-i64size : i])) } return i64, nil }
// BigEndian in-place data conversion for any architecture func readFileInt64BE(filename string) ([]int64, error) { b, err := os.ReadFile(filename) if err != nil { return nil, err } const i64Size = int(unsafe.Sizeof(int64(0))) i64Ptr := (*int64)(unsafe.Pointer(unsafe.SliceData(b))) i64Len := len(b) / i64Size i64 := unsafe.Slice(i64Ptr, i64Len) for i, j := i64Size, 0; i <= len(b); i, j = i+i64Size, j+1 { i64[j] = int64(binary.BigEndian.Uint64(b[i-i64Size : i])) } return i64, nil }
Das obige ist der detaillierte Inhalt vonWas ist der effizienteste Weg, eine Byte-Datei in ein int64-Slice einzulesen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!