MATLAB 中 mean2 的计算性能
calculation performance for mean2 in MATLAB
为什么直接执行 mean 函数更快?
Ig = rgb2gray(imread('test.png'));
n = 100000;
tic;
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
tic;
for ii=1:n
M2 = mean2(Ig);
end
toc
大约 n = 1000
,但 mean2
更快。但是随着迭代次数的增加,速度变慢了。
Elapsed time is 45.934058 seconds.
Elapsed time is 46.392206 seconds.
我怀疑 mean2 内部正在做这样的事情:
out = sum(x(:),'double') / numel(x)
x(:)
和 'double'
可能是原因吗?
运行一些测试代码后的结论:1)在你的代码中,当迭代次数大于 1000 时,mean2
显得更慢的原因是因为将代码组织成的惩罚功能。 MATLAB 需要为函数创建一个作用域,并在函数调用结束时终止它。从下面的测试条件可以看出,我在代码中直接实现了 mean2。 2) 根据@rayryeng 的评论,当数组很大时(至少在我的测试条件下),首先展开会加快计算速度。 3) sum(Ig(:),'double')
中的 'double'
参数占用了一些时间,实际上是不必要的,因为 sum
returns double
数据类型即使没有该参数。
我用来测试的代码如下:
Img = rgb2gray(imread('test2.tif')); % this is an rgb image larger than 1000x1000
Ig = Img(1:250,1:250);
n = 100000;
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 250x250')
tic;
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 250x250')
tic;
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 250x250')
tic;
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 250x250')
clear M1 M2 M3 M4
Ig = Img(1:500,1:500);
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 500x500')
tic
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 500x500')
tic
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 500x500')
tic
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 500x500')
Ig = Img(1:1000,1:1000);
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 1000x1000')
tic
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 1000x1000')
tic
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 1000x1000')
tic
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 1000x1000')
结果是:
Elapsed time is 2.115313 seconds.
for sum(sum(Ig))/numel(Ig) 250x250
Elapsed time is 5.753932 seconds.
for mean2(Ig) 250x250
Elapsed time is 5.626373 seconds.
for sum(Ig(:),'double')/numel(Ig) 250x250
Elapsed time is 5.425690 seconds.
for sum(Ig(:))/numel(Ig) 250x250
Elapsed time is 6.349700 seconds.
for sum(sum(Ig))/numel(Ig) 500x500
Elapsed time is 6.810287 seconds.
for mean2(Ig) 500x500
Elapsed time is 6.840604 seconds.
for sum(Ig(:),'double')/numel(Ig) 500x500
Elapsed time is 6.455498 seconds.
for sum(Ig(:))/numel(Ig) 500x500
Elapsed time is 23.772897 seconds.
for sum(sum(Ig))/numel(Ig) 1000x1000
Elapsed time is 22.071418 seconds.
for mean2(Ig) 1000x1000
Elapsed time is 21.862069 seconds.
for sum(Ig(:),'double')/numel(Ig) 1000x1000
Elapsed time is 21.498514 seconds.
for sum(Ig(:))/numel(Ig) 1000x1000
为什么直接执行 mean 函数更快?
Ig = rgb2gray(imread('test.png'));
n = 100000;
tic;
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
tic;
for ii=1:n
M2 = mean2(Ig);
end
toc
大约 n = 1000
,但 mean2
更快。但是随着迭代次数的增加,速度变慢了。
Elapsed time is 45.934058 seconds.
Elapsed time is 46.392206 seconds.
我怀疑 mean2 内部正在做这样的事情:
out = sum(x(:),'double') / numel(x)
x(:)
和 'double'
可能是原因吗?
运行一些测试代码后的结论:1)在你的代码中,当迭代次数大于 1000 时,mean2
显得更慢的原因是因为将代码组织成的惩罚功能。 MATLAB 需要为函数创建一个作用域,并在函数调用结束时终止它。从下面的测试条件可以看出,我在代码中直接实现了 mean2。 2) 根据@rayryeng 的评论,当数组很大时(至少在我的测试条件下),首先展开会加快计算速度。 3) sum(Ig(:),'double')
中的 'double'
参数占用了一些时间,实际上是不必要的,因为 sum
returns double
数据类型即使没有该参数。
我用来测试的代码如下:
Img = rgb2gray(imread('test2.tif')); % this is an rgb image larger than 1000x1000
Ig = Img(1:250,1:250);
n = 100000;
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 250x250')
tic;
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 250x250')
tic;
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 250x250')
tic;
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 250x250')
clear M1 M2 M3 M4
Ig = Img(1:500,1:500);
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 500x500')
tic
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 500x500')
tic
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 500x500')
tic
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 500x500')
Ig = Img(1:1000,1:1000);
tic
for ii=1:n
M1 = sum(sum(Ig))/numel(Ig);
end
toc
disp(' for sum(sum(Ig))/numel(Ig) 1000x1000')
tic
for ii=1:n
M2 = mean2(Ig);
end
toc
disp(' for mean2(Ig) 1000x1000')
tic
for ii=1:n
M3 = sum(Ig(:),'double')/numel(Ig);
end
toc
disp(' for sum(Ig(:),''double'')/numel(Ig) 1000x1000')
tic
for ii=1:n
M4 = sum(Ig(:))/numel(Ig);
end
toc
disp(' for sum(Ig(:))/numel(Ig) 1000x1000')
结果是:
Elapsed time is 2.115313 seconds. for sum(sum(Ig))/numel(Ig) 250x250
Elapsed time is 5.753932 seconds. for mean2(Ig) 250x250
Elapsed time is 5.626373 seconds. for sum(Ig(:),'double')/numel(Ig) 250x250
Elapsed time is 5.425690 seconds. for sum(Ig(:))/numel(Ig) 250x250
Elapsed time is 6.349700 seconds. for sum(sum(Ig))/numel(Ig) 500x500
Elapsed time is 6.810287 seconds. for mean2(Ig) 500x500
Elapsed time is 6.840604 seconds. for sum(Ig(:),'double')/numel(Ig) 500x500
Elapsed time is 6.455498 seconds. for sum(Ig(:))/numel(Ig) 500x500
Elapsed time is 23.772897 seconds. for sum(sum(Ig))/numel(Ig) 1000x1000
Elapsed time is 22.071418 seconds. for mean2(Ig) 1000x1000
Elapsed time is 21.862069 seconds. for sum(Ig(:),'double')/numel(Ig) 1000x1000
Elapsed time is 21.498514 seconds. for sum(Ig(:))/numel(Ig) 1000x1000