এই উত্তরের নীচে কিছু বেঞ্চমার্কিং কোড রয়েছে, যেহেতু আপনি স্পষ্ট করেছিলেন যে আপনি নির্বিচারে for
লুপগুলি এড়িয়ে চলার চেয়ে কার্য সম্পাদনে আগ্রহী ।
আসলে, আমি মনে করি for
লুপগুলি এখানে সম্ভবত সবচেয়ে পারফরম্যান্ট বিকল্প। যেহেতু "নতুন" (2015 বি) জেআইটি ইঞ্জিনটি চালু হয়েছিল ( উত্স ) for
লুপগুলি অন্তর্নিহিতভাবে ধীর নয় - বাস্তবে তারা অভ্যন্তরীণভাবে অনুকূলিত হয়।
আপনি বেঞ্চমার্ক থেকে দেখতে পারেন যে এখানেmat2cell
টমাসসকোডিংয়ের দেওয়া বিকল্পটি খুব ধীর ...
যদি আমরা স্কেলটিকে আরও পরিষ্কার করার জন্য সেই লাইনটি থেকে মুক্তি পাই তবে আমার splitapply
পদ্ধতিটি মোটামুটি ধীর, অবচার্ডনের যথার্থ বিকল্পটি কিছুটা ভাল তবে দ্রুত (এবং তুলনীয়) বিকল্পগুলি হয় arrayfun
(থমাসের পরামর্শ অনুসারে) বা for
লুপ ব্যবহার করছে। নোট করুন যে arrayfun
মূলত for
বেশিরভাগ ব্যবহারের ক্ষেত্রে ছদ্মবেশে লুপ হয়, সুতরাং এটি কোনও আশ্চর্যজনক টাই নয়!
for
কোডের পঠনযোগ্যতা এবং সেরা পারফরম্যান্সের জন্য আপনাকে একটি লুপ ব্যবহার করার পরামর্শ দিচ্ছি ।
সম্পাদনা করুন :
যদি আমরা ধরে নিই যে লুপিং দ্রুততম পদ্ধতির হয় তবে আমরা find
কমান্ডটি ঘিরে কিছু আশাবাদী করতে পারি ।
বিশেষভাবে
M
যৌক্তিক করুন । নীচের প্লটটি দেখায় যে, এটি তুলনামূলকভাবে ছোটের জন্য দ্রুততর হতে পারে M
তবে বড়দের জন্য ধরণের রূপান্তরকরণের ধীরে ধীরে ধীর হতে পারে M
।
M
কোনও অ্যারে 1:size(M,2)
ব্যবহারের পরিবর্তে সূচকে যুক্তিযুক্ত ব্যবহার করুন find
। এটি লুপের সবচেয়ে ধীরতম অংশ ( find
কমান্ড) এড়িয়ে চলে এবং ধরণের রূপান্তর ওভারহেডকে ছাড়িয়ে যায়, এটি দ্রুত বিকল্প হিসাবে তৈরি করে।
এখানে সেরা অভিনয়ের জন্য আমার প্রস্তাবনাটি দেওয়া হল:
function A = f_forlooplogicalindexing( M )
M = logical(M);
k = 1:size(M,2);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = k(M(r,:));
end
end
আমি এটি নীচের মানদণ্ডে যুক্ত করেছি, এখানে লুপ-স্টাইল পদ্ধতির তুলনা করা হল:
বেঞ্চমার্কিং কোড:
rng(904); % Gives OP example for randi([0,1],3)
p = 2:12;
T = NaN( numel(p), 7 );
for ii = p
N = 2^ii;
M = randi([0,1],N);
fprintf( 'N = 2^%.0f = %.0f\n', log2(N), N );
f1 = @()f_arrayfun( M );
f2 = @()f_mat2cell( M );
f3 = @()f_accumarray( M );
f4 = @()f_splitapply( M );
f5 = @()f_forloop( M );
f6 = @()f_forlooplogical( M );
f7 = @()f_forlooplogicalindexing( M );
T(ii, 1) = timeit( f1 );
T(ii, 2) = timeit( f2 );
T(ii, 3) = timeit( f3 );
T(ii, 4) = timeit( f4 );
T(ii, 5) = timeit( f5 );
T(ii, 6) = timeit( f6 );
T(ii, 7) = timeit( f7 );
end
plot( (2.^p).', T(2:end,:) );
legend( {'arrayfun','mat2cell','accumarray','splitapply','for loop',...
'for loop logical', 'for loop logical + indexing'} );
grid on;
xlabel( 'N, where M = random N*N matrix of 1 or 0' );
ylabel( 'Execution time (s)' );
disp( 'Done' );
function A = f_arrayfun( M )
A = arrayfun(@(r) find(M(r,:)),1:size(M,1),'UniformOutput',false);
end
function A = f_mat2cell( M )
[i,j] = find(M.');
A = mat2cell(i,arrayfun(@(r) sum(j==r),min(j):max(j)));
end
function A = f_accumarray( M )
[val,ind] = ind2sub(size(M),find(M.'));
A = accumarray(ind,val,[],@(x) {x});
end
function A = f_splitapply( M )
[r,c] = find(M);
A = splitapply( @(x) {x}, c, r );
end
function A = f_forloop( M )
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = find(M(r,:));
end
end
function A = f_forlooplogical( M )
M = logical(M);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = find(M(r,:));
end
end
function A = f_forlooplogicalindexing( M )
M = logical(M);
k = 1:size(M,2);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = k(M(r,:));
end
end
for
লুপগুলি এড়ানোর জন্য চান ? এই সমস্যার জন্য, ম্যাটল্যাবের আধুনিক সংস্করণগুলি সহ, আমি দৃ strongly়ভাবে সন্দেহ করি যে একটিfor
লুপটি দ্রুততম সমাধান হতে পারে। আপনার যদি পারফরম্যান্স সমস্যা হয় তবে আমার সন্দেহ হয় আপনি পুরানো পরামর্শের ভিত্তিতে সমাধানের জন্য ভুল জায়গায় খুঁজছেন।