如何在Matlab中对结构进行"引用"?

ana*_*lyg 7 performance matlab reference

在我的程序中,我有一个大的(例如100x100)结构数组,每个结构都有相当数量的数据(例如1000个数字,以及其他一些字段).例如:

for x = 100 : -1 : 1
    for y = 100 : -1 : 1
        database(y,x).data = rand(30);
        database(y,x).name = sprintf('my %d %d', x, y);
    end
end
Run Code Online (Sandbox Code Playgroud)

我想用我的数据计算10-20行代码; 例如:

for x = 10 : 90
    for y = 10 : 90
        for dx = -9 : 9
            for dy = -9 : 9
                result = result + database(y + dy, x + dx).data(1, 1);
                result = result + 2 * database(y + dy, x + dx).data(1, 2) * database(y + dy, x + dx).data(2, 2);
                ... % more stuff here
            end
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

我的代码将数据库的当前元素称为database(y + dy, x + dx).为了缩短它,我给它一个名字(C++称之为"引用"):

temp = database(y + dy, x + dx);
result = result + temp.data(1, 1);
result = result + 2 * temp.data(1, 2) * temp.data(2, 2);
Run Code Online (Sandbox Code Playgroud)

这使我的代码更短更清晰.但是,这也慢得多,并且分析显示分配temp = ...占用了我执行时间的70%.

所以我的假设是Matlab 复制了大数据库元素的内容,耗费了我的时间.我认为Matlab应该足够聪明,可以进行"写时复制",也就是说,只有在以后更改时才复制这些东西.但是,这不是我的情况 - 我的代码只从数据库中读取,并没有改变它.

那么,我怎样才能对结构进行有效的只读引用呢?

Den*_*din 1

好吧,当你这样做时,肯定会发生复制:

temp = database(y + dy, x + dx) 
Run Code Online (Sandbox Code Playgroud)

也许可以通过使用以下方法来减少:

temp = database(y + dy, x + dx).data
Run Code Online (Sandbox Code Playgroud)

但显然,只有当您只对这部分代码中的数据感兴趣时,这才有效。

话虽如此,我不确定您是否可以在不使用不方便的方法来构建数据的情况下解决这个问题。首先,您可以在替换所有 by 后对代码进行基准测试,tempdatabase(y + dy, x + dx)确保避免复制确实有帮助。如果是这样,您可以尝试输入database(y + dy, x + dx)子函数,因为如果足够的话,子函数中的变量通常与读取访问一起使用。但是,我不确定这是否也适用于部分变量。

如果以上方法都没有帮助,请考虑书中一些最古老的建议:

为了对大数据块进行有效计算,请考虑使用矩阵。