主要内容

有效利用内存的策略

该主题解释了在MATLAB中有效使用内存的几种技术®

使用适当的数据存储

MATLAB为您提供不同尺寸的数据类,例如双倍的UINT8,因此您无需使用大型类来存储较小的数据。例如,使用该存储1,000个小的无符号整数值所需的记忆少7 kbUINT8班级比上课双倍的

使用适当的数字类

您在MATLAB中使用的数字类取决于您的预期操作。默认类双倍的给出最佳的精度,但是每个内存元素需要8个字节才能存储。如果您打算执行复杂的数学(例如线性代数),则必须使用浮点类类,例如双倍的或者单身的。这单身的课程仅需要4个字节。您可以做些什么单身的课程,但大多数MATLAB数学操作都得到了支持。万博1manbetx

如果您只需要执行简单的算术,而将原始数据表示为整数,则可以在MATLAB中使用整数类。以下是数字类,内存需求(字节)和受支持的操作的列表。万博1manbetx

类(数据类型) 字节 万博1manbetx支持操作
单身的 4 大多数数学
双倍的 8 所有数学
逻辑 1 逻辑/条件操作
INT8,UINT8 1 算术和一些简单的功能
INT16,UINT16 2 算术和一些简单的功能
INT32,UINT32 4 算术和一些简单的功能
INT64,UINT64 8 算术和一些简单的功能

存储数据时减少开销量

MATLAB数组(内部实现为mxarrays)需要空间将有关数据的元信息存储在内存中,例如类型,尺寸和属性。每个数组大约需要104个字节。当您有大量(例如,数百或数千个)时,这个开销才成为一个问题mxarrays(例如,标量)。这谁是命令列出了变量使用的内存,但不包括此开销。

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

单元阵列由单独的mxarrays对于每个元素。结果,带有许多小元素的单元阵列的开销很大。

结构需要每个字段类似的开销。具有许多字段和小东西的结构的开销很大,应避免。与包含大数字阵列的字段相比,具有数字标量字段的大量结构需要更多的内存。

另请注意,尽管MATLAB将数字阵列存储在连续的内存中,但结构和单元格数组并非如此。有关更多信息,请参阅MATLAB如何分配内存

将数据导入适当的MATLAB班级

从二进制文件中读取数据时弗雷德,这是一个普遍的错误,仅指定文件中的数据类,而不是MATLAB在工作空间中使用的数据类别。结果,默认双倍的即使您仅读取8位值也使用。例如,

fid = fopen('name_file_of_uint8s.bin','r');a = fread(fid,1e3,'uint8');%需要8K名称大小字节类属性a 1000x1 8000 double a = fread(fid,1e3,'uint8 => uint8');%需要1K的名称大小字节类属性A 1000x1 1000 UINT8

尽可能使阵列稀疏

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

a =眼(1000);%全矩阵,对角上的矩阵为=稀疏(a);%稀疏矩阵只有非零元素whos名称大小字节类属性A 1000x1000 8000000 double as 1000x1000 24008双稀疏

您可以看到,此数组仅需要约24 kb的稀疏存储,但大约需要8 MB作为完整矩阵。通常,对于稀疏的双阵列NNZ非零元素和NCOL列,所需的内存是:

  • 16 *NNZ+ 8 *NCOL+ 8个字节(在64位机器上)

请注意,MATLAB在稀疏阵列上支万博1manbetx持大多数但不是全部的数学操作。

避免临时数据副本

您可以通过避免创建不必要的数据副本来显着减少所需的内存量。

避免创建临时数组

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

a =零(1E6,1);as = single(a);

使用一个命令进行两个操作是更有效的内存效率:

a = zeros(1e6,1,'single');

使用repmat功能,阵列预定和为了循环是处理非双重数据的其他方法,而无需在内存中临时存储。

使用嵌套功能通过更少的参数

使用大型数据集时,请注意,如果调用函数修改其值,则MATLAB将制作输入变量的临时副本。这会暂时加倍存储数组所需的内存,如果没有足够的内存,则会导致MATLAB生成错误。

在这种情况下使用较少内存的一种方法是使用嵌套功能。嵌套功能共享所有外部功能的工作空间,从而使嵌套功能访问其通常范围之外的数据。在此处显示的示例中,嵌套功能setrowval可以直接访问外部功能的工作空间myfun,使得不需要在函数调用中传递变量的副本。什么时候setrowval修改值一个,它在调用功能的工作区中修改它。无需使用其他内存来保存单独的数组来调用该函数,也无需返回修改后的值一个

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

回收使用的内存

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

定期将大数据保存到磁盘

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

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

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

a = rand(1e5);b = rand(1e5);记不清。更多信息清除a = rand(1e5);%新数组

相关话题