登录
首页 >  Golang >  Go问答

用 Go 加载数据的效率最高的方式

来源:stackoverflow

时间:2024-03-23 09:15:32 176浏览 收藏

为了在 Go 程序中高效地加载大量数据,建议避免使用 XLS 格式。相反,采用自定义的数据格式,直接写入二进制文件中的列数和行数,然后一次性写入所有数据。这种方法可以显著提高加载速度,示例代码仅需 400 毫秒即可写入和读取 300,000 行 x 40 列的 float32 数据。

问题内容

我需要定期将超过 300'000 行 x 78 列 的数据加载到我的 go 程序中。

目前我使用(import github.com/360entsecgroup-skylar/excelize):

xlsx, err := excelize.OpenFile("/media/test snaps.xlsm")
if err != nil {
    fmt.Println(err)
    return
}

//read all rows into df
df := xlsx.GetRows("data")

在使用三星 960 evo 系列 - m.2 内置 ssd 的体面 pc 上大约需要 4 分钟。

有没有更快的方法来加载这些数据?目前,我读取数据所花费的时间比处理数据的时间要多。我也愿意接受其他文件格式。


解决方案


正如评论中所建议的,不要使用 xls 格式,而是使用自定义的快速数据格式来读取和写入表。

最基本的情况,只需将列数和行数写入一个二进制文件,然后一次性写入所有数据。这将非常快,我创建了一个小示例 here,它仅将 300.000 x 40 float32 写入文件并将其读回。在我的机器上,这大约需要 400 毫秒和 250 毫秒(请注意,文件在写入后在缓存中很热,初次读取时可能需要更长的时间)。

package main

import (
    "encoding/binary"
    "os"

    "github.com/gonutz/tic"
)

func main() {
    const (
        rowCount = 300000
        colCount = 40
    )
    values := make([]float32, rowCount*colCount)
    func() {
        defer tic.Toc()("write")
        f, _ := os.Create("file")
        defer f.Close()
        binary.Write(f, binary.LittleEndian, int64(rowCount))
        binary.Write(f, binary.LittleEndian, int64(colCount))
        check(binary.Write(f, binary.LittleEndian, values))
    }()
    func() {
        defer tic.Toc()("read")
        f, _ := os.Open("file")
        defer f.Close()
        var rows, cols int64
        binary.Read(f, binary.LittleEndian, &rows)
        binary.Read(f, binary.LittleEndian, &cols)
        vals := make([]float32, rows*cols)
        check(binary.Read(f, binary.LittleEndian, vals))
    }()
}

func check(err error) {
    if err != nil {
        panic(err)
    }
}

好了,本文到此结束,带大家了解了《用 Go 加载数据的效率最高的方式》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>