Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance MATLAB中mean2的计算性能_Performance_Matlab_Mean - Fatal编程技术网

Performance MATLAB中mean2的计算性能

Performance MATLAB中mean2的计算性能,performance,matlab,mean,Performance,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,仍然意味着2更快。但随着迭代次数的增加,它会变得更慢 Elapsed time is 45.934058 seconds. Elapsed time is

为什么平均函数的直接实现更快

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
,仍然
意味着2
更快。但随着迭代次数的增加,它会变得更慢

Elapsed time is 45.934058 seconds.
Elapsed time is 46.392206 seconds.
我怀疑它在做这样的事情:

out = sum(x(:),'double') / numel(x)

x(:)
'double'
可能是原因吗?

运行一些测试代码后得出的结论:1)在您的代码中,
意味着2
在迭代次数大于1000时显得较慢的原因是因为将代码组织到函数中会受到惩罚。MATLAB需要为函数创建一个作用域,并在函数调用结束时终止它。这可以从下面的测试条件中看出,我在代码中直接实现了mean2。2) 根据@rayryeng的评论,当数组很大时(至少在我的测试条件下),首先展开可以加快计算速度。3)
sum(Ig(:),'double')
中的
'double'
参数会占用一些时间,实际上是不必要的,因为
sum
即使没有该参数也会返回
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')
结果是:

运行时间为2.115313秒。 对于sum(sum(Ig))/numel(Ig)250x250

运行时间为5.753932秒。 平均值2(Ig)250x250

运行时间为5.626373秒。 对于总和(Ig(:),'double')/numel(Ig)250x250

运行时间为5.425690秒。 对于总和(Ig(:)/numel(Ig)250x250

运行时间为6.349700秒。 对于sum(sum(Ig))/numel(Ig)500x500

运行时间为6.810287秒。 平均值2(Ig)500x500

运行时间为6.840604秒。 对于总和(Ig(:),'double')/numel(Ig)500x500

运行时间为6.455498秒。 对于总和(Ig(:)/numel(Ig)500x500

运行时间为23.772897秒。 对于sum(sum(Ig))/numel(Ig)1000x1000

运行时间为22.071418秒。 平均2(Ig)1000x1000

运行时间为21.862069秒。 对于总和(Ig(:),'double')/numel(Ig)1000x1000

运行时间为21.498514秒。 对于总和(Ig(:)/numel(Ig)1000x1000


就是这样
mean2
将2D矩阵展开为向量,并直接计算平均值。展开可能是您获得性能提升的原因。我一辈子都不记得在哪里见过它,但有一些计时测试(这里)在计算前展开有助于加快速度。。。但是,随着数组变大,性能会下降,因为您要展开更多的元素。可以肯定的是,可以使用
timeit
计时吗?@rayryeng但这里不是数组变大;这只是重复的次数(如果我理解正确的话)@LuisMendo-这就是我误读代码时发生的情况。是的,你是对的。。。这是一个奇怪的反常现象。不管怎样,差别很小。我不确定我是否向您发出了邀请,但如果您有时间,请访问我们的MATLAB和Octave聊天室:)我看到您经常在这里回答问题。我们经常在那里谈论事情和交流。不过完全取决于你。如果没有,不用担心。祝你好运谢谢你的邀请:)我一定会偶尔来看看的!我从你们那里学到了很多!