Was ist der effizienteste Weg, eine Byte-Datei in ein int64-Slice einzulesen?

PHPz
Freigeben: 2024-02-09 11:36:09
nach vorne
941 Leute haben es durchsucht

将字节文件读入 int64 切片的最有效方法是什么?

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!

Frageninhalt

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)
Nach dem Login kopieren

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?

Workaround

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)
Nach dem Login kopieren

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
}
Nach dem Login kopieren

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
}
Nach dem Login kopieren
// 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
}
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!