php小编子墨在这里为大家解答一个常见的问题:“将字节文件读入 int64 切片的最有效方法是什么?”当我们需要将字节文件读入 int64 切片时,可以采用以下方法:首先,使用 file_get_contents 函数读取字节文件,然后使用 unpack 函数将字节文件解包为 int64 切片。这样的方法简单高效,能够快速地将字节文件转换为 int64 切片,满足我们的需求。希望这个方法能够帮助到大家!
我有几个打包的 int64 文件。我需要它们在内存中作为 int64 切片。问题是文件加在一起超过了机器内存大小的一半,因此空间有限。 go 中的标准选项类似于:
a := make([]int64, f.Size()/8) binary.Read(f, binary.LittleEndian, a)
不幸的是,binary
包将立即分配一个大小为 f.size()*8
的 []byte
,并耗尽内存。
如果我一次读取每个字节并将其复制到切片中,它确实可以工作,但这速度太慢了。
理想的情况是将 []byte
直接转换为 []int64
,只是告诉编译器“好吧,这些现在是整数”,但显然这是行不通的。有什么方法可以完成类似的东西?可能使用不安全的包或在绝对需要时放入 c 中?
我有几个打包的 int64 文件。我需要它们在内存中作为 int64 切片。问题是文件加在一起超过了机器内存大小的一半,因此空间有限。
go 中的标准选项类似于:
a := make([]int64, f.size()/8) binary.read(f, binary.littleendian, a)
不幸的是,二进制包将立即分配一个大小为 f.size()*8 的 []byte,并耗尽内存。
所有函数都使用最少的内存。
// 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 }
例如,为了amd64(littleendian)架构和littleendian数据最大效率(无需数据转换),请使用readfileint64se
。
字节顺序谬误 - rob 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 }
Atas ialah kandungan terperinci Apakah cara yang paling berkesan untuk membaca fail bait ke dalam kepingan int64?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!