这两种在Matlab中删除元素的方法有什么区别:
ElementsToDelete = [0 0 1 0 1 0 0 1 1 0]
A = 1:10
A(ElementsToDelete) = []
%Versus
A = 1:10
A = A(~ElementsToDelete)
有时一种方法比另一种更合适吗?效率有区别吗?还是它们完全可以互换?
这两种在Matlab中删除元素的方法有什么区别:
ElementsToDelete = [0 0 1 0 1 0 0 1 1 0]
A = 1:10
A(ElementsToDelete) = []
%Versus
A = 1:10
A = A(~ElementsToDelete)
有时一种方法比另一种更合适吗?效率有区别吗?还是它们完全可以互换?
试试这个:
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 以上。
我的猜测是,删除(即,用 分配)通过逻辑索引在内部循环中[]
每次出现 a 时重写整个数组。true
这是非常低效的,当像这样测试它时变得很明显。另一方面,重新赋值可以预先确定新数组的大小并相应地对其进行初始化;无需重写。
为什么 JIT 不将一个编译成另一个对我来说是一个谜,因为删除是一种更直观的符号恕我直言。但是,正如您所看到的,与替代方案相比,它效率低下,因此应谨慎使用。永远不要在循环中使用它!