通过= [] vs重新分配矩阵删除矩阵元素

时间:2012-09-14 09:07:40

标签: matlab

在Matlab中删除元素的这两种方法有什么区别:

ElementsToDelete = [0 0 1 0 1 0 0 1 1 0]

A = 1:10
A(ElementsToDelete) = []

%Versus

A = 1:10
A = A(~ElementsToDelete)

有时候一种方法比另一种方法更合适吗?效率有差异吗?或者它们完全可以互换?

1 个答案:

答案 0 :(得分:8)

试试这个:

A = rand(1e3, 1);
b = A<0.5;

tic; 
for ii = 1:1e5
    a = A;       
    a(b) = [];
end
toc

tic; 
for ii = 1:1e5
    a = A;        
    a = a(~b);
end
toc

结果:

Elapsed time is 1.654146 seconds
Elapsed time is 1.126325 seconds

因此差异是1.5的速度因素有利于重新分配。然而,这更糟糕了:

A = rand(1e4, 1);

stop = 0;    
for jj = 1:10
    a = A;
    start = tic;
    for ii = 1:1e5
        a(a < rand) = [];
    end
    stop = stop + toc(start);
end
avg1 = stop/10


stop = 0;    
for jj = 1:10
    a = A;
    start = tic;
    for ii = 1:1e5
        a = a(a > rand);
    end
    stop = stop + toc(start);
end
avg2 = stop/10

avg1/avg2

结果:

avg1 = 1.1740235 seconds
avg2 = 0.1850463 seconds

avg1/avg2 = 6.344485136963019

因此,因素增加到6以上。

我的猜测是删除(即,使用[]分配)通过逻辑索引在内部循环中每次出现true时重写整个数组。这是毫无希望的低效率,正如在这样测试时显而易见的那样。另一方面,重新分配可以预先确定新阵列的大小并相应地初始化它;不需要重写。

为什么JIT不会将一个编译成另一个对我来说是一个谜,因为删除是一个更直观的符号恕我直言。但是,如您所见,与替代品相比,它效率低下,因此应谨慎使用。 永远不要在循环内使用它!