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

Golang 读取 csv 在内存中消耗的空间是磁盘空间的 2 倍以上

Golang 读取 csv 在内存中消耗的空间是磁盘空间的 2 倍以上

Go
喵喔喔 2022-06-27 15:06:36
我正在使用 Golang 将大量 CSV 文件加载到结构中。结构是type csvData struct {    Index   []time.Time    Columns map[string][]float64}    我有一个解析器,它使用:csv.NewReader(file).ReadAll()然后我遍历行,并将值转换为它们的类型:time.Time或float64.问题是这些文件在磁盘上占用 5GB 空间。一旦我将它们加载到内存中,它们就会消耗 12GB!我使用ioutil.ReadFile(path)并发现这与预期的一样几乎完全是磁盘上的大小。这是我的解析器的代码,为了便于阅读,省略了错误,如果你能帮助我排除故障:var inMemoryRepo = make([]csvData, 0)func LoadCSVIntoMemory(path string) {    parsedData := csvData{make([]time.Time, 0), make(map[string][]float64)}    file, _ := os.Open(path)    reader := csv.NewReader(file)    columnNames := reader.Read()    columnData := reader.ReadAll()    for _, row := range columnData {        parsedData.Index = append(parsedData.Index, parseTime(row[0])) //parseTime is a simple wrapper for time.Parse        for i := range row[1:] {                                       //parse non-index numeric columns            parsedData.Columns[columnNames[i]] = append(parsedData.Columns[columnsNames[i]], parseFloat(columnData[i])) //parseFloat is wrapper for strconv.ParseFloat        }    }    inMemoryRepo = append(inMemoryRepo, parsedData)}我尝试通过在函数调用结束时将columnData和设置为零来进行故障排除,但没有任何变化。reader
查看完整描述

2 回答

?
慕工程0101907

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

这没有什么令人惊讶的。在您的磁盘上只有 CSV 文本的字符(字节)。当您将它们加载到内存中时,您会从文本中创建数据结构。

例如,一个float64值在内存中需要 64 位,即:8 个字节。如果您有输入 text "1",则为 1 个单字节。然而,如果你创建一个float64等于 的值1,那仍然会消耗 8 个字节。

此外,strings 存储有一个字符串头 ( reflect.StringHeader),它是 2 个整数值(在 64 位架构上为 16 个字节),并且该头指向实际的字符串数据。有关详细信息,请参阅Golang中的字符串内存使用情况。

切片也是类似的数据结构:reflect.SliceHeader. 标头由 3 个整数值组成,即使切片中没有元素,在 64 位架构上也是 24 个字节。

在此之上的结构可能具有填充(字段必须与某些值对齐),这再次增加了开销。有关详细信息,请参阅规格:尺寸和对齐保证

Go Maps 是 hashmaps,它也有相当多的开销,有关详细信息,请参阅为什么切片值有时会过时但从不映射值?,对于内存使用情况,请参阅Golang maps 保留多少内存?


查看完整回答
反对 回复 2022-06-27
?
白衣非少年

TA贡献1155条经验 获得超0个赞

很少将整个文件读入内存是一个好主意。


如果你的 csv 是 100GiB 怎么办?


如果您的转换不涉及多个记录,也许您可以应用以下算法:


open csv_reader (source file)

open csv_writer (destination file)

for row in csv_reader

    transform row

    write row into csv_writer

close csv_reader and csv_write


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 239 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号