相比R中同样的方法textscan在Matlab使用过多RAM(textscan in Matlab

2019-09-22 13:10发布

我在Linux Mint的V12运行Matlab的R2011b和R版本2.13.1与16 GB的RAM。

我有一个CSV文件。 前5行(和标题)为:

#RIC,Date[G],Time[G],GMT Offset,Type,Price,Volume
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.68,1008
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.68,1008
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.66,300
DAEG.OQ,07-JUL-2011,15:10:03.424,-4,Trade,1.65,1000
DAEG.OQ,07-JUL-2011,15:10:03.464,-4,Trade,1.65,3180

该文件较大(约900MB)。 鉴于字符和数字数据的组合,如下一个可以读取这个文件到MATLAB:

fid1 = fopen('/home/MyUserName/Temp/X.csv');
D = textscan(fid1, '%s%s%s%f%s%f%f', 'Delimiter', ',', 'HeaderLines', 1);
fclose(fid1);

尽管文件是900MB,运行上面的代码时,系统监视器显示我的内存使用量大约2GB至10GB跳跃。 更糟的是,如果我试图用一个稍大的CSV文件相同的过程(约1.2 GB),我在RAM 16GB马克塞斯和Matlab从未设法读完数据(它只是停留停留在“忙”模式)。

如果我想读取相同的文件到R,我可能会使用:

D <- read.csv("/home/MyUserName/Temp/X.csv", stringsAsFactors=FALSE)

这需要比Matlab的长了一点,但系统监视器显示我的内存使用率只有从2GB跳转到3.3GB(更合理给出的原始文件的大小)。

我的问题有两个部分:

1)为什么textscan在这种情况下这样的记忆猪?

2)是否有另一种方法,我可以用得到这个类型到Matlab我的系统上的1.2GB csv文件,而不杏的RAM?

编辑:只是为了澄清,我很好奇,是否存在一个唯一的MATLAB的解决方案,即我不感兴趣包括使用不同的语言,打破了CSV文件成小块(因为这是一个什么样的解决方案我已经在做)。 对不起Trav1s,我应该让这个明确从一开始。

Answer 1:

这个问题可能是正在读入那些“%S”字符串以Matlab的cellstrs,这对于低基数串的存储器效率不好的数据结构。 Cellstrs是憋了如此之大的表格数据。 每个串最终得到存储在单独的原始char阵列,每个具有大约400个字节的开销和碎片问题。 有了您的900MB的文件,看起来十八般百万行; 每行4个字符串,这是大约10-20 GB cellstrs来保存这些字符串。 啊。

你想要的是那些字符串转换为紧凑的基本数据类型,因为它们可以进来,而不是让所有18个百万行一次咕噜咕噜中笨重的电池串。 日期和时间戳为datenums或者你使用任何数字表示,而那些低基数的字符串既可以作为2-d char数组或一个分类变量的一些等价的。 (鉴于你的数据集大小,你可能想这些字符串表示的查找表,而不是字符的简单数字标识符。)

一旦你对你紧凑的数据结构决定的,有几种方法可以在加载它你可以只打破了读中块纯Matlab的:使用textscan()在循环中调用在同一时间在1000线看,分析和转换在该块的cellstrs在其紧凑的形式,缓存所有的结果,和cat在读的最后在一起。 这会保持峰值内存要求较低。

如果你打算做了很多这样的工作,和性能问题,你可能要下降到Java和写自己的解析器,因为他们进来,可以转换的字符串和日期,递给他们回到matlab所前更紧凑的数据类型。 这并不难,而Java方法可以直接从MATLAB调用,因此这可能只是一种算作使用单独的语言。



Answer 2:

2)你可以尝试使用csvread命令。 我不知道如何表现进行比较,但至少它是一个另类。

另一种方法是使用读取C或AWK快得多的语言文件,然后把它分解成更小的文件。 阅读许多小文件按顺序将内存小于一个大文件密集。



文章来源: textscan in Matlab uses excessive RAM compared to similar method in R