主要内容

高效使用内存的策略

这个主题解释了几个技术,以使用内存在MATLAB有效®

使用适当的数据存储

MATLAB提供了不同大小的数据类,例如双倍的uint8,因此您不需要使用大型类来存储较小的数据段。例如,使用该方法存储1,000个小的无符号整数值只需要7 KB的内存uint8而不是和它一起双倍的

使用适当的数字类

你在MATLAB中应该使用的数值类取决于你想要的动作。默认的类双倍的提供最佳精度,但需要每个内存元素的8个字节来存储。如果您打算执行复杂的数学,如线性代数,则必须使用浮点等级,例如a双倍的要么.的类只需要4个字节。与您可以做的事情有一些局限性类,但支持大多数Matlab数学运营。金宝app

如果您只需要执行简单的算术并将原始数据表示为整数,则可以使用MATLAB中的整数类。下面是数字类、内存需求(以字节为单位)和支持的操作的列表。金宝app

类(数据类型) 字节 金宝app支持的运营
4 大多数数学
双倍的 8 所有的数学
逻辑 1 逻辑/条件操作
int8, uint8 1 算术和一些简单的函数
int16, uint16 2 算术和一些简单的函数
int32, uint32 4 算术和一些简单的函数
INT64,INT64. 8 算术和一些简单的函数

存储数据时减少开销量

MATLAB数组(内部实现为mxArrays)需要空间来存储关于内存中数据的元信息,例如类型、维度和属性。每个数组大约需要104个字节。只有当你有大量的小数目(例如成百上千)时,这种开销才会成为问题mxArrays(例如,标量)。的命令列出变量所使用的内存,但不包括此开销。

因为简单的数字阵列(包括一个mxarray.)有最少的开销,你应该尽可能使用它们。当数据太复杂以存储在简单的数组(或矩阵)中时,可以使用其他数据结构。

单元格数组由独立的单元格数组组成mxArrays为每个元素。因此,包含许多小元素的单元数组的开销很大。

结构的每个字段需要相似的开销。具有许多字段和小内容的结构开销很大,应该避免。具有数字标量字段的大型结构数组比包含大型数字数组的字段的结构需要多得多的内存。

另请注意,当MATLAB存储连续内存中的数字阵列时,这不是结构和单元格阵列的情况。有关更多信息,请参阅Matlab如何分配内存

将数据导入适当的MATLAB

从二进制文件读取数据时吓唬,它是一个常见的错误,只能在文件中仅指定数据的类,而不是数据MATLAB的类在工作区中使用。结果,默认值双倍的即使您只读取8位值也会使用。例如,

FID = FOPEN('lange_file_of_uint8s.bin','r');a = fread(fid,1e3,'uint8');%需要8k whos名称大小字节类属性a 1000x1 8000双a = fread(fid,1e3,'uint8 => uint8');%需要1k whos一个名称大小字节类属性a 1000x1 1000 uint8

尽可能使数组稀疏

如果您的数据包含许多零,请考虑使用稀疏阵列,仅存储非零元素。以下示例比较了稀疏和完整的存储要求:

一个=眼(1000);%对角为1的满矩阵=稀疏矩阵(A);类属性A 1000x1000 8000000 double As 1000x1000 24008 double Sparse

您可以看到此阵列只需要24 KB才能存储为稀疏,但大约为8 MB作为完整矩阵。一般来说,对于稀疏的双数组nnz非零元素和ncol列,所需的内存是:

  • 16 *nnz+ 8 *ncol+ 8字节(在64位机器上)

请注意,MATLAB支持稀疏数组的金宝app大多数(但不是全部)数学运算。

避免数据的临时副本

通过避免创建不必要的数据临时副本,可以显著减少所需的内存量。

避免创建临时数组

避免创建大型临时变量,并在不再需要时清除临时变量的练习。例如,此代码创建存储为临时变量的零数组一个,然后转换一个单精度:

一个= 0 (1)e6, 1);=单(A);

使用一个命令执行这两个操作是更多的内存有效:

= 0 (1 e6, 1, '单');

使用repmat.函数、数组预分配和循环是处理非双精度数据而不需要内存中临时存储的其他方法。

使用嵌套函数来通过更少的参数

在处理大型数据集时,请注意,如果被调用的函数修改了输入变量的值,则MATLAB会临时复制输入变量。这暂时使存储数组所需的内存翻倍,如果没有足够的内存可用,会导致MATLAB产生错误。

在这种情况下使用较少的内存的一种方法是使用嵌套函数。嵌套函数共享所有外部功能的工作空间,使嵌套功能访问其通常范围之外的数据。在此示例中,嵌套功能setrowval是否可以直接访问外部功能的工作空间myfun,这样就不需要在函数调用中传递变量的副本。当setrowval修改价值一个,它在调用函数的工作空间中修改它。不需要使用额外的内存来保存正在调用的函数的单独数组,并且也无需返回修改的值一个

功能myfun a = magic(500);setrowval(400,0)disp(''(399:401,1:10)的新值是')a(399:401,1:10)函数setrowval(行,值)a(行,:) =价值;结束

回收旧的内存

增加您所提供的内存量的一个简单方法是清除您不再使用的大型阵列。

定期将大数据保存到磁盘

如果您的程序生成大量数据,请考虑定期将数据写入磁盘。保存该部分数据后,使用清除函数从内存中删除变量并继续生成数据。

清除内存中不再需要的旧变量

当您重复或交互地处理一个非常大的数据集时,首先清除旧变量,为新变量腾出空间。否则,在覆盖变量之前,MATLAB需要相等大小的临时存储空间。例如,

兰德(1 = e5);b =兰德(1 e5);内存不足。更多信息clear a a = rand(1e5);%新数组

相关话题