【问题标题】:Deleting matrix elements by = [] vs reassigning matrix通过 = [] 删除矩阵元素 vs 重新分配矩阵
【发布时间】:2012-09-14 22:13:16
【问题描述】:

这两种在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


    【解决方案1】:

    试试这个:

    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 不将一个编译成另一个对我来说是个谜,因为删除是一种更直观的符号恕我直言。但是,如您所见,与替代方案相比,它效率低下,因此应谨慎使用。 切勿在循环中使用它!

    【讨论】:

    • 对 =[] 方法有什么要论证的吗?
    • 请注意,将~ 放在循环之外会使第二个版本更快。
    • @H.Muster 是的,但这对第一个版本不公平 :)
    • @RodyOldenhuis:我刚刚注意到,通过将b = a&lt;0.5; 移出循环,第一个版本与第二个版本差不多快。在第一个版本中,每次迭代都计算索引是否有特定原因?
    • @H.Muster 不,这只是一个愚蠢的复制粘贴错误。查看我的新编辑。
    猜你喜欢
    • 2017-05-29
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 2014-09-21
    • 2012-02-13
    • 2019-03-23
    • 2017-09-14
    • 1970-01-01
    相关资源
    最近更新 更多