script is slower than command window

I wrote a program to convert from rgb to hue the size of data1 matrix is high (768778) so it takes about 2 - 3 secs to run but when I put the code into script, it turns into very slow with same input as data1 (i waited more than minute)
here is my code (in command window, in case of script it is added "function [color]= rg2hue(datai)" and "end" at the end)
what should i do to run it in script
color=ones(length(data1),1);
for i=1:length(data1)
% color(i,1)=0.2989*data1(i,4)+0.5870*data1(i,5)+ 0.1140*data1(i,6);
max_v=max([data1(i,4) data1(i,5) data1(i,6)]);
min_v=min([data1(i,4) data1(i,5) data1(i,6)]);
deltac=max_v-min_v;
if deltac==0
huer=0;
else
if (data1(i,4)==max_v)
huer=(data1(i,5)-data1(i,6))/deltac;
elseif (data1(i,5)==max_v)
huer=(data1(i,4)-data1(i,6))/deltac;
else
huer=(data1(i,4)-data1(i,5))/deltac;
end
huer=huer*60;
if (huer<0)
huer=huer+360;
end
end
color(i,1)=huer;
end

Answers (1)

Jan
Jan on 7 Jun 2017
Edited: Jan on 7 Jun 2017
Start with vectorizing the determination of the min and max values:
function color = rg2hue(data)
color = zeros(size(data, 1),1);
max_vM = max(data(:, 4:6), [], 2);
min_vM = min(data(:, 4:6), [], 2);
for k = 1:size(data, 1)
max_v = max_vM(k);
min_v = min_vM(k);
deltac = (max_v - min_v) / 60;
if deltac ~= 0
if data(k,4) == max_v
huer = (data(k,5) - data(k,6)) / deltac;
elseif data(i,5) == max_v
huer = (data(k,4) - data(k,6)) / deltac;
else
huer = (data(k,4) - data(k,5)) / deltac;
end
if huer < 0
huer = huer + 360;
end
color(k) = huer;
end
end
This reduces the runtime from 3.06 to 0.14 seconds for a [1e6, 6] input. A complete vectorization will be faster:
function color = rg2hue(data)
[max_v, index] = max(data(:, 4:6), [], 2);
min_v = min(data(:, 4:6), [], 2);
deltac = (max_v - min_v) / 60;
color = zeros(size(data, 1), 1);
m = (index == 4);
color(m) = (data(m, 5) - data(m, 6)) ./ deltac(m);
m = (index == 5);
color(m) = (data(m, 4) - data(m, 6)) ./ deltac(m);
m = (index == 6);
color(m) = (data(m, 4) - data(m, 5)) ./ deltac(m);
m = (color < 0);
color(m) = color(m) + 360;
color(deltac == 0) = 0;
This runs in 0.087 seconds on my computer, so you see the main work was done by vectorizing min and max. You can find such bottlenecks in your code by using the profiler.
Functions can be handles better by the JIT acceleration than scripts. But under R2009a I do not get minuts of runtime. Therefore I assume you had another problem.
I've replaced length(data1) by size(data1, 1), because then the functions works properly if the input has less then 6 pixels (rows) also.
Initializing the output by ones only to overwrite it by zeros on demand is a waste of time. Better create it by zeros and omit the assigning of other values. This does not save a lot of time, but the code gets leaner.

Asked:

on 7 Jun 2017

Edited:

Jan
on 7 Jun 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!