为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中加载数据的最快方法

在 Go 中加载数据的最快方法

Go
牛魔王的故事 2023-03-21 17:21:57
我需要定期将300'000 rows x 78 columns数据加载到我的 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 dfdf := xlsx.GetRows("data")在使用三星 960 EVO 系列 - M.2 内置 SSD 的体面 PC 上大约需要4分钟。有没有更快的方法来加载这些数据?目前,读取数据比处理数据花费的时间更多。我也对其他文件格式开放。
查看完整描述

1 回答

?
杨魅力

TA贡献1811条经验 获得超5个赞

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

在最基本的情况下,只需将列数和行数写入二进制文件,然后一次性写入所有数据。这将非常快,我在这里创建了一个小示例,它只将 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)

    }

}


查看完整回答
反对 回复 2023-03-21
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信