Wednesday, July 15, 2020

ความเร็วในการคูณ 2D matrix กับ 3D array แบบ slice by slice

โพสนี้จะขอเปรียบเทียบความเร็วในการคูณ element-wise 3D matrix แบบ slice by slice อธิบายเป็นภาษาไทยลำบาก วาดรูปให้ดูเลยดีกว่า
สมมติเรามี 2D matrix A ที่อยากจะเอาไปคูณแบบ element by element กับ 2D matrix B ที่มีจำนวน r ชั้น เราสามารถเขียนโค้ดได้หลายแบบ แต่ในที่นี้จะเปรียบเทียบแค่ 2 แบบ คือแบบ vectorization กับ แบบใช้คำสั่ง bsxfun เราจะข้ามการคูณแบบใช้ for loop ไป เพราะรู้คำตอบอยู่แล้วว่าช้ากว่าทั้ง2แบบนี้มาก แต่เนื่องจาก MATLAB เค้าเป็นจ้าวแห่ง matrix operation (ชื่อเค้าก็บอกอยู่ MATrix LABoratory) และ bsxfun เป็น operation ที่ low level มากๆ เลยน่าสนใจว่าใครจะไวกว่ากัน 

โค้ดที่ใช้ในการเปรียบเทียบเป็นดังนี้

close all; clear; clc;

% 2D matrix times each slice of 3D matrix
N = [10,50,100,200,500,700];
t1 = zeros(1,length(N));
t2 = t1;
for ii = 1:length(N)
    n = N(ii);
    A  = rand(n,n);
    B  = rand(n,n,n);
    tic;
    C = bsxfun(@times, A, B);
    t1(ii) = toc;

    tic;
    D = ones(1,1,n);
    A = A.*D;
    C = A.*B;
    t2(ii) = toc;
end
h = plot(N,t1,'-*b',N,t2,'-*r');axis tight;
h(1).LineWidth = 2;
h(2).LineWidth = 2;
set(gca,'FontSize',14);
legend('bsxfun','vectorization');
xlabel('n'); ylabel('time(s)');


ผลสรุปออกมา คืออออออ...... bsxfun ชนะค่าาาาา ยิ่งmatrixมีขนาดใหญ่มากยิ่งทิ้งห่าง เพราะงั้นหากใครต้องการความไวในการเขียนโค้ด ดิชั้นแนะนำให้หันมาใช้ bsxfun จ้าา

No comments:

Post a Comment