この質問に対する別の答え!今回は、次の4つの方法のパフォーマンスを比較します。
- 私のオリジナルの方法
- EitanTの元の方法(空を処理しない)
- 文字列を使用したEitanTの改善された方法
- 新しい方法:単純なforループ
- 別の新しい方法:ベクトル化された、空に安全なバージョン
テストコード:
% Set up test
N = 1e5;
S(N).b = [];
for ii = 1:N
S(ii).b = randi(6); end
% Rody Oldenhuis 1
tic
sol1 = find( cellfun(@(x)isequal(x,6),{S.b}) );
toc
% EitanT 1
tic
sol2 = find([S.b] == 6);
toc
% EitanT 2
tic
str = sprintf('%f,', S.b);
values = textscan(str, '%f', 'delimiter', ',', 'EmptyValue', NaN);
sol3 = find(values{:} == 6);
toc
% Rody Oldenhuis 2
tic
ids = false(N,1);
for ii = 1:N
ids(ii) = isequal(S(ii).b, 6);
end
sol4 = find(ids);
toc
% Rody Oldenhuis 3
tic
idx = false(size(S));
SS = {S.b};
inds = ~cellfun('isempty', SS);
idx(inds) = [SS{inds}]==6;
sol5 = find(idx);
toc
% make sure they are all equal
all(sol1(:)==sol2(:))
all(sol1(:)==sol3(:))
all(sol1(:)==sol4(:))
all(sol1(:)==sol5(:))
仕事中の私のマシンでの結果(AMD A6-3650 APU(4コア)、4GB RAM、Windows 7 64ビット):
Elapsed time is 28.990076 seconds. % Rody Oldenhuis 1 (cellfun)
Elapsed time is 0.119165 seconds. % EitanT 1 (no empties)
Elapsed time is 22.430720 seconds. % EitanT 2 (string manipulation)
Elapsed time is 0.706631 seconds. % Rody Oldenhuis 2 (loop)
Elapsed time is 0.207165 seconds. % Rody Oldenhuis 3 (vectorized)
ans =
1
ans =
1
ans =
1
ans =
1
私のホームボックス(AMD Phenom(tm)II X6 1100T(6コア)、16GB RAM、Ubuntu64 12.10):
Elapsed time is 0.572098 seconds. % cellfun
Elapsed time is 0.119557 seconds. % no emtpties
Elapsed time is 0.220903 seconds. % string manipulation
Elapsed time is 0.107345 seconds. % loop
Elapsed time is 0.180842 seconds. % cellfun-with-string
そのJITが大好きです:)
そしてすごい...2つのシステムがなぜそんなに異なって振る舞うのか誰もが知っていますか?
また、ほとんど知られていない事実-cellfun
可能な文字列引数の1つを使用すると、信じられないほど高速になります(これは、匿名関数が必要とするオーバーヘッドの量を示します...)。
それでも、空がないことを絶対に確信できる場合は、EitanTの元の答えを探してください。それがMatlabの目的です。確信が持てない場合は、ループに進んでください。