2011-07-14 7 views
2

なぜデータセット配列へのインデックス作成が遅いのですか? dataset.subsref関数のピークは、データセットのすべての列がセル配列に格納されていることを示します。しかし、セルのインデックス付けは、データセットのインデックス付けよりもはるかに高速です。これは、フードの下のセル配列にインデックスを付けることです。私の推測では、これはMATLAB OOPのオーバーヘッドと関係しているということです。どのようにこれをスピードアップするためのアイデア? Statistics Toolboxでデータセット配列のインデックス作成が非常に遅い

%% 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. 

EDIT:私はより多くの私が見ている問題のようにする例を更新しました。 dataset.subref - "b = a.data {varIndex};"の行262に膨大な時間が費やされています。それは単純な細胞逆参照であるので、私には非常に奇妙です。私は奇妙なオーバーヘッドなしに "a.data"にインデックスを付けることができるOOPのトリックがあるのだろうかと思っています。

EDIT2: Andrewの提案によると、これをMatWorksのバグとして提出しました。彼らから何かが聞こえると更新されます。

EDIT3: Matlabは応答し、問題を認識しており、今後のリリースで修正する予定だと述べています。彼らは、この問題は細胞アレイに特有であり、可能であればそれらを回避しようとしていると述べた。

+1

MATLABプロファイラではどのように見えますか? –

+0

+1 Richieのコメントは、Matlabのパフォーマンスに関する質問に対する最良の答えです。 –

+0

時間の90%以上がdataset.subrefの行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では、時間の半分はメソッド呼び出しのオーバーヘッド、残りはfind()、strcmp()、およびsubsref内の他の操作です。 subsrefは他のメソッドを順番に呼び出しません。

編集2:改訂された例は、はるかに高いタイミングを示しています。メソッド呼び出しのオーバーヘッドはそれをすべて考慮しません。

+0

はい、ds.datを保存することは時間を節約するための良いトリックです。ループで同じ列が必要になることがわかったら、私はいつもそれを行います。 accel offはJITをオフにするので、セルアレイループのタイミングをスキューしません。 –

関連する問題