Matlab:什么更快?是否预定义有用的对象?
Matlab: What's faster? Predefining helpful objects or not?
我必须在 matlab 中使用非常大的矩阵进行计算。我已经确保在可能的情况下使用矩阵运算等。现在尝试微调。
所以设 A、B、C 和 D 为矩阵:
C=A*B;
D=cos(C);
似乎微不足道的是以下会更快(如果我错了请纠正我):
D=cos(A*B)
我的问题是,如果对预定义对象的调用次数更多,是否会更快:
D=f1(A*B) + f2(A*B) + …;
而不是预定义 C=A*B(我认为这会节省很多计算)。我有很多这种表达式,所以一些一般性的见解会很有用(至少要知道它依赖于什么样的参数,即矩阵大小)。
是的,您可以通过更改以下语句的代码来加快速度:
D=f1(A*B) + f2(A*B) + …;
像这样的陈述:
C = A * B;
D=f1(C) + f2(C) + …;
因为显然执行的乘法较少。我见过很多 matlab 代码重复表达式,因为作者只是边复制边粘贴。
至少,要维护和调试的表达式会少一些。所以一般不要重复自己。
根据经验我知道改变:
y = f1(A*B) + f2(A*B)...
到
C = A*B;
y = f1(C) + f2(C)...
当您遇到优化代码的场景时速度更快 - 中间变量 "C" 的操作如上所述多次完成。
当操作只完成一次时,它不太可能产生性能改进或降低,因为我认为操作是在变量传递给函数之前由 Matlab 内联完成的。
为了帮助证明这一点,您可以查看下面的基准函数,该函数测试变量 A 和 B 的单个和多个操作 (3)。
底部的图显示了结果,与上面的点一致
function benchmark
% test array
testArray = 100:100:5000; % 5000 will take quite a while - to test start with smaller (e.g. 500)
% preallocate
sep=zeros(numel(testArray),1);
inline=sep;
sepcombined = sep;
inlinecombined = sep;
fcnSep1 = @() sepfcn;
fcnInline1 = @() inlinefcn;
fcnSep2 = @() sepfcn2;
fcnInline2 = @() inlinefcn2;
% set up array counter
count = 1;
% run throuh all tests
for i=testArray
% create A&B
A = zeros(i,i)+2;
B = A+1;
% run single actions
sep(count) = timeit (fcnSep1);
inline(count) = timeit (fcnInline1);
% combined actions
sepcombined(count) = timeit (fcnSep2);
inlinecombined(count) = timeit (fcnInline2);
% increment the counter
count = count + 1;
% monitor progress
disp ( i );
end
% use nested functions for the actions
function sepfcn
C = A*B;
sum(C);
end
function inlinefcn
sum(A*B);
end
function sepfcn2
C = A*B;
sum(C)+max(C)+min(C);
end
function inlinefcn2
sum(A*B)+max(A*B)+min(A*B);
end
%% plot the results
figure;
subplot ( 2, 1, 1 );
plot ( testArray, sep, 'r-', testArray, inline,'b-' );
legend ( 'sep', 'inline' )
title ( 'single action' );
ylabel ( 'time (s)' )
xlabel ( 'matrix size' )
subplot ( 2, 1, 2 );
plot ( testArray, sepcombined, 'r-', testArray, inlinecombined,'b-' );
legend ( 'sep', 'inline' )
title ( 'multiple actions' );
xlabel ( 'matrix size' )
ylabel ( 'time (s)' )
end
我必须在 matlab 中使用非常大的矩阵进行计算。我已经确保在可能的情况下使用矩阵运算等。现在尝试微调。 所以设 A、B、C 和 D 为矩阵:
C=A*B;
D=cos(C);
似乎微不足道的是以下会更快(如果我错了请纠正我):
D=cos(A*B)
我的问题是,如果对预定义对象的调用次数更多,是否会更快:
D=f1(A*B) + f2(A*B) + …;
而不是预定义 C=A*B(我认为这会节省很多计算)。我有很多这种表达式,所以一些一般性的见解会很有用(至少要知道它依赖于什么样的参数,即矩阵大小)。
是的,您可以通过更改以下语句的代码来加快速度:
D=f1(A*B) + f2(A*B) + …;
像这样的陈述:
C = A * B;
D=f1(C) + f2(C) + …;
因为显然执行的乘法较少。我见过很多 matlab 代码重复表达式,因为作者只是边复制边粘贴。
至少,要维护和调试的表达式会少一些。所以一般不要重复自己。
根据经验我知道改变:
y = f1(A*B) + f2(A*B)...
到
C = A*B;
y = f1(C) + f2(C)...
当您遇到优化代码的场景时速度更快 - 中间变量 "C" 的操作如上所述多次完成。
当操作只完成一次时,它不太可能产生性能改进或降低,因为我认为操作是在变量传递给函数之前由 Matlab 内联完成的。
为了帮助证明这一点,您可以查看下面的基准函数,该函数测试变量 A 和 B 的单个和多个操作 (3)。
底部的图显示了结果,与上面的点一致
function benchmark
% test array
testArray = 100:100:5000; % 5000 will take quite a while - to test start with smaller (e.g. 500)
% preallocate
sep=zeros(numel(testArray),1);
inline=sep;
sepcombined = sep;
inlinecombined = sep;
fcnSep1 = @() sepfcn;
fcnInline1 = @() inlinefcn;
fcnSep2 = @() sepfcn2;
fcnInline2 = @() inlinefcn2;
% set up array counter
count = 1;
% run throuh all tests
for i=testArray
% create A&B
A = zeros(i,i)+2;
B = A+1;
% run single actions
sep(count) = timeit (fcnSep1);
inline(count) = timeit (fcnInline1);
% combined actions
sepcombined(count) = timeit (fcnSep2);
inlinecombined(count) = timeit (fcnInline2);
% increment the counter
count = count + 1;
% monitor progress
disp ( i );
end
% use nested functions for the actions
function sepfcn
C = A*B;
sum(C);
end
function inlinefcn
sum(A*B);
end
function sepfcn2
C = A*B;
sum(C)+max(C)+min(C);
end
function inlinefcn2
sum(A*B)+max(A*B)+min(A*B);
end
%% plot the results
figure;
subplot ( 2, 1, 1 );
plot ( testArray, sep, 'r-', testArray, inline,'b-' );
legend ( 'sep', 'inline' )
title ( 'single action' );
ylabel ( 'time (s)' )
xlabel ( 'matrix size' )
subplot ( 2, 1, 2 );
plot ( testArray, sepcombined, 'r-', testArray, inlinecombined,'b-' );
legend ( 'sep', 'inline' )
title ( 'multiple actions' );
xlabel ( 'matrix size' )
ylabel ( 'time (s)' )
end