11

しばらく前に、私はこの質問に答えました。

[3 6]目的:範囲内にあるこの行列の値の数を数えます。

A = [2 3 4 5 6 7;
     7 6 5 4 3 2]

私はそれを行う12の異なる方法を思いつきました:

count = numel(A( A(:)>3 & A(:)<6 ))      %# (1)
count = length(A( A(:)>3 & A(:)<6 ))     %# (2)
count = nnz( A(:)>3 & A(:)<6 )           %# (3)
count = sum( A(:)>3 & A(:)<6 )           %# (4)

Ac = A(:);
count = numel(A( Ac>3 & Ac<6 ))          %# (5,6,7,8)
%# prevents double expansion
%# similar for length(), nnz(), sum(),
%# in the same order as (1)-(4)

count = numel(A( abs(A-(6+3)/2)<3/2 ))   %# (9,10,11,12)
%# prevents double comparison and & 
%# similar for length(), nnz(), sum()
%# in the same order as (1)-(4)

ということで、どちらが早いか調べてみました。テストコード:

A = randi(10, 50);
tic
for ii = 1:1e5

    %# method is inserted here

end
toc

結果 (ベスト オブ 5 ラン、すべて秒単位):

%# ( 1): 2.981446
%# ( 2): 3.006602
%# ( 3): 3.077083
%# ( 4): 2.619057
%# ( 5): 3.011029
%# ( 6): 2.868021
%# ( 7): 3.149641
%# ( 8): 2.457988
%# ( 9): 1.675575
%# (10): 1.675384
%# (11): 2.442607
%# (12): 1.222510

ここcount = sum(( abs(A(:)-(6+3)/2) < (3/2) ));に行くのが最速の方法のようです...

<足し算と足し算の2分割で1本をトレード、約定abs時間は半分以下!これがなぜなのか説明できる人はいますか?

JIT コンパイラーは、おそらく除算/加算をメモリー内の単一の値に置き換えますが、それでもabs...Branch の予測ミスはありますか? このような単純なものにはばかげているようです...

4

1 に答える 1