主要内容

避免不必要的数据副本

将值传递给函数

当调用带有输入参数的函数时,MATLAB®将呼叫函数工作区的值复制到正在调用的函数中的参数变量中。但是,Matlab应用各种技术,以避免在不需要时进行这些值的副本。

MATLAB不提供一种方法来定义一个值的引用,就像c++语言那样。相反,MATLAB允许多个输出和多个输入参数,这样你就知道函数中有什么值函数中有什么值。

复制写作

如果函数不修改输入参数,则MATLAB不会使输入变量中包含的值的副本。

例如,假设您将一个大数组传递给一个函数。

一个=兰德(1)e7, 1);B = f1 (A);

这个函数F1将输入数组中的每个元素相乘X经过1.1并将结果赋给变量y

函数Y = f1(X) Y = X *1.1;% X是a的共享副本结尾

因为函数不修改输入值,局部变量X和变量一种在呼叫者的工作区中共享数据。后F1执行,分配给的值一种没有改变。的变量B.在调用者的工作区中包含按元素进行乘法的结果。输入通过值传递。但是,在调用时不会进行复制F1

这个函数F2确实修改了输入变量的本地副本,导致本地副本与输入不共享一种.的价值X在该函数中现在是输入变量的独立副本一种在调用者的工作区中。当F2将结果返回给呼叫者的工作区,本地变量X被摧毁。

一个=兰德(1)e7, 1);B = f2 (A);
函数Y = f2(X) X = X *1.1;% X是A的独立副本y = x;% Y是X的共享副本结尾

通过输入作为MATLAB表达式

您可以使用从函数返回的值作为另一个函数的输入参数。例如,使用兰特功能为函数创建输入F2直接。

B = f2(兰德(1)e7, 1));

表示返回值的唯一变量兰特为临时变量X在该函数的工作空间中F2.在调用者的工作区中没有这些值的共享或独立副本。直接传递函数输出节省了在被调用函数中创建输入值副本所需的时间和内存。当不再使用输入值时,这种方法是有意义的。

分配就地

当您不需要保留原始输入值时,可以将函数的输出分配给您作为输入提供的相同变量。

一个= f2 (A);

就地赋值遵循前面描述的写时复制行为:修改输入变量值将导致这些值的临时副本。

MATLAB可以在某些条件下应用内存优化。考虑以下示例。这可以优化函数在变量中创建大量随机数一种.然后调用局部函数絮状物,路过一种作为输入,并将本地函数的输出分配给相同的变量名。

函数canBeOptimized A = rand(1e7,1);= fLocal ();结尾函数x = Flocal(x)x = x. * 1.1;结尾

因为呼叫本地功能,a = flocal(a),将输出赋给变量一种, MATLAB不需要保留的原始值一种在执行功能期间。修改为X里面絮状物不要导致数据的副本。赋值X = X * 1.1修改X在适当的位置,无需为乘法结果分配新数组。消除局部函数中的副本可以节省内存并提高大型数组的执行速度。

但是,如果本地函数中的分配需要数组索引,则MATLAB无法应用此优化。例如,修改创建的单元格数组updatecells.需要索引到数组中X在本地功能全球在地化.形式中的循环赋值我X{我}= {}* 1.1创建数据的副本X {}.对于单元格数组的每个元素,工作区中都有两个副本全球在地化

函数updatecells c = num2cell(rand(1e7,1));C = Glocal(c);结尾函数x = Glocal(x)为了i = 1:长度(x)x {i} = x {i} * 1.1;结尾结尾

还有一些附加的限制。当函数抛出错误后可以使用变量时,MATLAB不能应用内存优化。因此,这种优化不会应用于脚本、命令行和调用求解,或在里面编码试着抓块。此外,MATLAB在执行所谓的函数期间直接访问原始变量时,MATLAB不会应用内存优化。例如,如果絮状物是一个嵌套函数,Matlab无法应用优化,因为可以使用父函数共享变量。最后,当分配的变量声明为全局或持久性时,MATLAB不应用内存优化。

调试代码,使用就地分配

当MATLAB应用于分配语句的地理优化时,分配左侧的变量设置为临时状态,使得MATLAB执行赋值语句的右侧之前使其无法访问。如果在将语句的右侧的结果分配给变量之前,MATLAB在调试器中停止,则检查左侧变量可以生成表示变量不可用的错误。

例如,该函数在变量的尺寸中具有不匹配的尺寸一种B.

函数a = inplace a = rand(100);b =兰特(99);DBStop.如果错误A = A. * B;结尾

执行该函数会抛出一个错误并在调试器中停止。

到位
矩阵维度必须同意。在inplace(第5行)A = A. * B中出错;5 a = a。* b;

试图查看变量的值一种虽然在调试模式下会导致错误,因为变量暂时不可用。

k >> A.
变量“A”不可访问。当一个变量出现在赋值语句的两边时,该变量可能在处理过程中暂时不可用。

要在调试时获得更大的灵活性,请重构代码以删除就地赋值。例如,将结果赋给另一个变量。

函数a = inplace a = rand(100);b =兰特(99);DBStop.如果错误%将结果赋给C而不是AC = A. * B;a = c;结尾

然后在调试器中可见变量A.

为什么按值传递语义

MATLAB在向函数传递参数和从函数返回值时使用按值传递语义。在某些情况下,按值传递会导致在被调用的函数中生成原始值的副本。然而,按值传递语义提供了某些优势。

在调用函数时,您知道在呼叫者的工作区中未修改输入变量。因此,您无需在函数内或呼叫站点内的输入副本只是为了防止可能修改这些值的可能性。仅修改分配给返回值的变量。

另外,如果在通过引用传递变量的函数中发生错误,还可以避免损坏工作空间变量。

处理对象

有一种特殊的物体叫做把手.包含相同句柄副本的所有变量都可以访问和修改相同的底层对象。处理对象在专用环境中是有用的,其中对象表示物理对象,例如窗口,绘图,设备或人,而不是像数字或矩阵等数学对象。

类派生的句柄对象处理类,它提供事件和监听器、析构函数方法以及对动态属性的支持等功能。万博1manbetx

有关值和句柄的更多信息,请参见手柄和价值类比较使用哪种类型的类

也可以看看

相关话题