变量似乎在每次循环迭代时都会改变大小 - 什么? [英] Variable appears to change size on every loop iteration - what?

查看:12
本文介绍了变量似乎在每次循环迭代时都会改变大小 - 什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写以下 Matlab 代码时:

When writing the following Matlab code:

for ii=1:n
    x(ii) = foo( ii ); % foo is some function of ii that cannot be vectorized.
end

我收到以下 m-lint 警告:

变量 x 似乎在每次循环迭代时都会改变大小

The variable x appears to change size on every loop iteration

我的问题:

  1. 这个警告是什么意思?
  2. 为什么每次迭代都改变变量大小是一件坏事?
  3. 如何解决这个问题?

<小时>

此问题与 此问题 不同,因为它处理的是预分配的更一般方面,而不是它的特定实例.


This question is not duplicate of this one, since it deals with more general aspects of preallocation, rather a specific instance of it.

推荐答案

嗯,第一件事.

这段代码在语法上是正确的,它将正确执行并返回预期的结果:x 的第 ii 元素将包含值 foo(二).
然而,在这段小代码运行之前,变量 x 并没有被定义.现在,当循环开始时,x(1) 被赋值为 foo(1),因此 Matlab 创建 x 作为长度-1 个数组.在第二次迭代中,x(2) 被赋值为 foo(2),因此 Matlab 需要将 x 更改为长度为 2,依此类推:x 在每次迭代时都会改变其长度/大小.

This code is correct in terms of syntax and it will execute correctly returning the expected result: the ii-th element of x will contain the value foo( ii ).
However, before this small piece of code runs, the variable x is not defined. Now, when the loop starts, x(1) is assigned the value foo( 1 ), and so Matlab creates x as a length-1 array. At the second iteration x(2) is assigned the value foo( 2 ) and so Matlab needs to change x to be of length 2, and so on: x changes its length/size at each iteration.

考虑当 x 每次迭代都改变它的大小时,后台会发生什么(在内存分配方面): 在每次迭代中,Matlab 需要找到一个空闲的内存空间来承载 的新大小>x.如果幸运的话,在 x 之后有足够的可用空间,所以所发生的只是更改分配给 x 的内存量并在右侧写入新值现货.
但是,如果在 x 之后没有足够的可用空间,Matlab 必须为 all 中的 ii-1 元素找到一个新位置x,为 x 分配这个新空间,复制所有 ii-1 值已经在 x 到新位置,并释放旧位置 x 使用.这种在后台发生的无分配复制操作可能非常耗时,尤其是当 x 很大时.

Consider what happens in the background (in terms of memory allocation) when x changes its size every iteration: At each iteration Matlab needs to find a free memory space to host the new size of x. If you are lucky, there is enough free space right after x so all that happens is a change to the amount of memory allocated to x and writing the new value at the right spot.
However, if there is not enough free space just after x, Matlab has to find a new spot for all the ii-1 elements already in x, allocate this new space for x, copy all ii-1 values already in x to the new spot, and free the old spot x used. This allocate-copy-free operations happening in the background can be extremely time consuming, especially when x is large.

最简单的解决方案是预先分配x需要循环之前的所有空间:

The simplest solution is to pre-allocate all the space x needs before the loop:

x = zeros(1,n); 
for ii=1:n
    x( ii ) = foo( ii );
end

通过预分配,我们确定 x 已预先分配了它需要的所有内存,因此在循环执行时不需要昂贵的内存分配/复制.

By pre-allocating we ascertain that x is allocated all the memory it requires up-front, thus no costly memory allocation/copy is needed when the loop is executing.

如果你太懒(像我一样)并且不想预先分配,你可以简单地:

If you are too lazy (like me) and don't want to pre-allocate you can simply:

for ii=n:-1:1
    x( ii ) = foo( ii );
end

这样,第一次 x 被分配一个值,它被分配给它的第 n-th 元素(最后一个),因此 Matlab 立即x 的所有 n 元素分配空间.
酷!

This way, the first time x is assigned a value it is assigned to its n-th element (the last one) and therefore Matlab immediately allocates room for all n elements of x.
Cool!

这篇关于变量似乎在每次循环迭代时都会改变大小 - 什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆