Heim >Backend-Entwicklung >Golang >Was ist der effizienteste Weg, eine Byte-Datei in ein int64-Slice einzulesen?

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

PHPz
PHPznach vorne
2024-02-09 11:36:09968Durchsuche

将字节文件读入 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)

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)

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen