Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang读取csv占用的内存空间是磁盘空间的2倍以上_Csv_Go - Fatal编程技术网

Golang读取csv占用的内存空间是磁盘空间的2倍以上

Golang读取csv占用的内存空间是磁盘空间的2倍以上,csv,go,Csv,Go,我正在使用Golang将大量CSV文件加载到结构中。 结构是 类型csvData结构{ 索引[]time.time 列映射[字符串][]浮点64 } 我有一个解析器,它使用: csv.NewReader(file).ReadAll() 然后我迭代行,并将值转换为它们的类型:time.time或float64 问题是这些文件在磁盘上占用5GB的空间。 一旦我将它们加载到内存中,它们就会消耗12GB 我使用了ioutil.ReadFile(path),发现这与预期的磁盘大小几乎完全相同

我正在使用Golang将大量CSV文件加载到结构中。 结构是

类型csvData结构{
索引[]time.time
列映射[字符串][]浮点64
}    
我有一个解析器,它使用:

csv.NewReader(file).ReadAll()
然后我迭代行,并将值转换为它们的类型:
time.time
float64

问题是这些文件在磁盘上占用5GB的空间。 一旦我将它们加载到内存中,它们就会消耗12GB

我使用了
ioutil.ReadFile(path)
,发现这与预期的磁盘大小几乎完全相同

以下是我的解析器代码,为了可读性,省略了错误,如果您能帮助我排除故障:

var inMemoryRepo=make([]csvData,0)
func LOADCSVINTOMERY(路径字符串){
parsedData:=csvData{make([]time.time,0),make(map[string][]float64)}
文件:=os.Open(路径)
读卡器:=csv.NewReader(文件)
columnNames:=reader.Read()
columnData:=reader.ReadAll()
对于u,行:=范围列数据{
parsedData.Index=append(parsedData.Index,parseTime(行[0])///parseTime是time.Parse的简单包装器
对于i:=范围行[1::///解析非索引数字列
parsedData.Columns[columnNames[i]=append(parsedData.Columns[columnsNames[i]],parseFloat(columnData[i])//parseFloat是strconv.parseFloat的包装器
}
}
inMemoryRepo=append(inMemoryRepo,解析数据)
}

在函数调用结束时,我尝试通过将
columnData
reader
设置为nil来进行故障排除,但没有任何更改。

这一点并不奇怪。磁盘上只有CSV文本的字符(字节)。当您将它们加载到内存中时,您可以从文本中创建数据结构

例如,
float64
值需要64位内存,即:8字节。如果您有一个输入文本
“1”
,则为1个单字节。但是,如果您创建一个等于
1
float64
值,它仍将消耗8个“是”

此外,
string
s存储有一个字符串头(),该头是2个整数值(64位体系结构上为16字节),该头指向实际的字符串数据。有关详细信息,请参阅

切片也是类似的数据结构:。报头由3个整数值组成,在64位体系结构中,即使片中没有元素,也是24字节

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


Go映射是hashmaps,它同样有相当大的开销,有关详细信息,请参阅,有关内存使用情况,请参阅,这一点并不奇怪。磁盘上只有CSV文本的字符(字节)。当您将它们加载到内存中时,您可以从文本中创建数据结构

例如,
float64
值需要64位内存,即:8字节。如果您有一个输入文本
“1”
,则为1个单字节。但是,如果您创建一个等于
1
float64
值,它仍将消耗8个“是”

此外,
string
s存储有一个字符串头(),该头是2个整数值(64位体系结构上为16字节),该头指向实际的字符串数据。有关详细信息,请参阅

切片也是类似的数据结构:。报头由3个整数值组成,在64位体系结构中,即使片中没有元素,也是24字节

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


Go映射是hashmaps,它同样有相当大的开销,有关详细信息,请参阅,有关内存使用情况,请参阅将整个文件读入内存很少是个好主意

如果您的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

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

如果您的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

主要原因是您没有按原样存储数据,而是试图将其存储为
地图
。您能告诉我更多信息吗?我是否缺少有关地图如何存储在内存中的重要知识?我将再次阅读,但如果您能给我您的见解,我将不胜感激。我已经阅读了,而且我似乎已经通过调用runtime.GC()解决了一些问题。现在它消耗了约8GB的内存!谢谢,主要原因是您没有按原样存储数据,而是试图将其存储为
地图
。您能告诉我更多信息吗?我是否缺少有关地图如何存储在内存中的重要知识?我将再次阅读,但如果您能给我您的见解,我将不胜感激。我已经阅读了,而且我似乎已经通过调用runtime.GC()解决了一些问题。现在它消耗了约8GB的内存!谢谢,所以我调用了runtime.GC(),这非常有帮助,并将内存使用量从12GB减少到8GB。通常计算为8*len(column)*列数仍然大致证实了磁盘大小。只要这是预期的行为,就可以了,我将尝试用其他方式进行优化。谢谢你的帮助!您好,所以我调用了runtime.GC(),这非常有帮助,并将内存使用量从12GB减少到8GB。通常计算为8*len(column)*列数仍然大致证实了磁盘大小。只要这是预期的行为,就可以了,我将尝试用其他方式进行优化。谢谢你的帮助!