2011-07-14 101 views
2

为什么索引到数据集数组这么慢?进入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”。

编辑2:根据安德鲁的建议,我已经将此作为一个错误提交给MatWorks。如果我从他们那里听到任何信息,将更新

EDIT3: Matlab的回应,并表示,他们意识到了这个问题现在将修复它在未来的版本。他们指出,这个问题是针对单元阵列的,如果可能的话尽量避免它们。

+1

它在MATLAB profiler下看起来像什么? –

+0

+1 Richie的评论是任何Matlab性能问题的最佳答案。 –

+0

超过90%的时间花费在dataset.subsref的第262行上,这是奇怪的b/c,它是一个简单的单元格取消引用。不幸的是,我给出的例子太简单了,无法显示。我会更新一个更现实的例子。 –

回答

3

是的,你很可能看到Matlab OOP方法调用的开销。与单元索引或其他一些语言的方法调用相比,它们非常昂贵。您的.513872秒/ 1e4〜=每次通话51微秒,这是几个MCOS方法调用的大致成本;他们在我见过的机器上每次约5-15微秒。所以这看起来像subsref()的方法开销自己调用,其他方法和属性访问它依次调用。

对于一些细节和讨论,请参见:Is MATLAB OOP slow or am I doing something wrong?

我不知道的一种方式,使这个速度,除了构建你的代码,以尽量减少通话“ds.dat”或其他方法。如果可能,在处理数据集时,调用“ds.dat”一次,将其保存在局部变量中并在那里使用,然后将其推回到ds对象。

警告:我不知道“功能加速”是什么,或者它会如何影响这些时间。

编辑:我把它扔到像里奇建议的剖析器。在我的R2009b上,看起来大约有一半的时间是方法调用开销,其余部分在subsref的find(),strcmp()和其他操作中; subsref不会依次调用任何其他方法。

编辑2:修改后的示例显示更高的计时。方法调用开销并不占所有这些。

+0

是的,保存ds.dat是节省时间的好方法。我总是这样做,如果我知道我将需要一个循环中的同一列。加速关闭关闭JIT,因此它不会扭曲单元阵列循环的时序。 –

相关问题