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

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

问题描述

编写以下 Matlab 代码时:

对于 ii=1:nx(ii) = foo(ii);% foo 是 ii 的一些不能向量化的函数.结尾

我收到以下 m-lint 警告:><块引用>

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

我的问题:

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

<小时>

这个问题与这个问题不同,因为它涉及预分配的更一般方面,而是它的一个具体实例.

解决方案

好吧,首先要做的事.

1.这个警告是什么意思?

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

2.为什么每次迭代都改变可变大小是一件坏事?

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

3.这个问题怎么解决?

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

x = zeros(1,n);对于 ii=1:nx( ii ) = foo( ii );结尾

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

该问题的另一种很酷的解决方案

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

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

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

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

I get the following m-lint warning:

The variable x appears to change size on every loop iteration

My question:

  1. What does that warning mean?
  2. Why is changing variable size every iteration is a bad thing?
  3. How can this problem be solved?


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

解决方案

Well, first thing first.

1. What does this warning mean?

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.

2. Why is changing variable size every iteration is a bad thing?

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.

3. How can this problem be solved?

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

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.

An alternative cool solution to the problem

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

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天全站免登陆