【发布时间】:2011-10-05 14:12:38
【问题描述】:
为什么索引到数据集数组这么慢? dataset.subsref 函数的峰值表明数据集的所有列都存储在一个元胞数组中。但是,单元格索引比数据集索引要快得多,后者只是索引到引擎盖下的单元格数组。我的猜测是,这与 MATLAB OOP 的一些开销有关。有关如何加快速度的任何想法?
%% Using R2011a, PCWIN64
feature accel off; % turn off JIT
dat = (1:1e6)';
dat2 = repmat({'abc'}, 1e6, 1);
celldat = {dat dat2};
ds = dataset(dat, dat2);
N = 1e2;
tic;
for j = 1:N
tmp = celldat{2};
end
toc;
tic;
for j = 1:N
tmp2 = ds.dat2; % 2.778sec spent on line 262 of dataset.subsref
end
toc;
feature accel on; % turn JIT back on
Elapsed time is 0.000165 seconds.
Elapsed time is 2.778995 seconds.
编辑:我已将示例更新为更像我所看到的问题。在 dataset.subsref -“b = a.data{varIndex};”的第 262 行上花费了大量时间。这对我来说很奇怪,因为它是一个简单的单元格取消引用。我想知道是否有一个 OOP 技巧可以让我在没有奇怪开销的情况下索引“a.data”。
EDIT2:根据 Andrew 的建议,我已将此作为错误提交给 MatWorks。如果我收到他们的任何消息,会更新。
EDIT3: Matlab 回应说他们现在已经意识到这个问题,并将在未来的版本中修复它。他们指出问题是特定于元胞数组的,并尽可能避免它们。
【问题讨论】:
-
在 MATLAB profiler 下是什么样子的?
-
+1 Richie 的评论是任何 Matlab 性能问题的最佳答案。
-
超过 90% 的时间花在 dataset.subsref 的第 262 行,这很奇怪,因为它是一个简单的单元格取消引用。不幸的是,我给出的例子太简单了,无法展示。我会更新一个更现实的例子。
-
@Rich C: "b = a.data{varIndex}" 不是简单的单元格取消引用。这 ”。”部分是 MCOS 对象字段访问,然后是“{}”单元格取消引用。我破解了 dataset.subsref 将其分成两行:“tmp = a.data; b = tmp{varIndex};”并重新分析它。所有时间都花在“a.data”字段访问上。同样,MCOS 开销。
-
等等,你修改后的代码只有 1e2 次通过?这是惊人的缓慢。对于 subsref 中的“a.data”字段访问,这是 20 毫秒,而不是微秒。除了正常的开销之外,这里还发生了一些可疑的事情。看起来那个时间与数据有关。例如。如果我将其更改为“dat = 42; dat2 = {'foo'};”,那么它会变快。几乎就像写时复制优化不起作用,它正在对数据进行大量复制。
标签: matlab