# Speeding up code

7 views (last 30 days)
Thomas Humphrey on 23 Nov 2011
I've written a code to calculate three numbers for me, however with the first for loop it takes forever to run compared to without it. I know it is over a large range but I was wondering if there was anyway to speed it up?
C_pd = Specific_Heat(T_d,X_d);
C_pb = Specific_Heat(T_b,X_b);
e = 0.1;
f = e;
g = 0.01;
i = 1;
k = 0;
l = 100;
m = k;
n = l;
for j=1:3
for T_f = k:e:l
C_pf = Specific_Heat(T_f,X_f);
a = M_f*C_pf*(T_f-T_cw);
for T_o = m:f:n
b = M_d*C_pd*(T_d-T_o) + M_b*C_pb*(T_b-T_o);
if abs(a-b)<g
T(1,i) = T_f;
T(2,i) = T_o;
i=i+1;
end
end
end
k = min(T(1,:));
l = max(T(1,:));
m = min(T(2,:));
n = max(T(2,:));
e = e/10;
f = f/10;
g = g/10;
end
The idea of this code is to calculate the three variables, starting with a range of 0:100 until they converge. I know the answers are supposed to be T_f = 68 and T_o = 36 however am currently getting no where near those as it is taking too long to converge.

Thomas Humphrey on 26 Nov 2011
Was able to solve this with 100 iterations of my code (the first for loop run 100 times) in less than a second as soon as this was purchased (cost £18)
before that it was taking over 20 seconds to do 3 loops.
can finally use my i7 to its full potential

Daniel Shub on 23 Nov 2011
Using these parameters
Specific_Heat = @(x,y)(1);
T_d = 1;
X_d = 1;
T_b = 1;
X_b = 1;
X_f = 1;
M_f = 1;
T_cw = 1;
M_d = 1;
M_b = 1;
The code takes 100 ms to run on my computer. While there are a number of ways of speeding up the code you gave us (e.g, initializing T and replacing the T_o for loop with a parfor loop), I think the bottleneck is probably with you Specific_Heat function.
Have you tried profiling your code?
doc profile
Daniel Shub on 23 Nov 2011
Don't worry about profiling or parfor loops yet. I timed it with tic and toc (doc tic). When you say you replaced specific_heat, does that mean you replaced
C_pf = Specific_Heat(T_f,X_f);
with
C_pf = 1;

Hin Kwan Wong on 23 Nov 2011
Parfor is not really beneficial unless you have quad cores or comput clusters. Looking at your code it will benefit a lot from vectorization instead.
Please read: "Techniques for Improving Performance" in MATLAB help. I learnt a lot from there and the profiler is very helpful. My code had 200x speed improvement.
First you need to make sure Specific_Heat supports vector as inputs. Then you start vectorizing the inner most for loop and work your way back
Hin Kwan Wong on 23 Nov 2011
I don't agree Daniel. This is because I have a dual core PC, and parfor runs actually slower with 2 worker even though I followed proper recommendations. The overhead depends on the nature of the operations in the for loop.
MATLAB as of 2010b is still notoriously slow with for loop. I optimised my code which contains intensive calculation which repeats over 835,000,000 times element by element for a input vector of size 1000. After vectorization there is still 835000 nested function loops but it ran much quicker, I had gained a factor of 200 times improvement in computation time after vectorizing. I measured it with tic toc and I am not bluffing. This was done a week ago when I was enlightened and educated by the help file. It's a very helpful read.

Daniel Shub on 23 Nov 2011
I missed it in my first answer ...
The variable T is growing in your inner loop. I got distracted by the i, and thought it would only grow a little bit. What is happening is that every time abs(a-b) < g, you need to allocate a new memory buffer for T that is one slot bigger than the current T. Then you need to copy the old T into the new memory buffer and finally add the new element in. This is hugely time consuming as the size of T grows.
You need to preallocate T in some way. Assuming 1 loop is speedy enough, and that you only want 1000 loops something like
C_pd = Specific_Heat(T_d,X_d);
C_pb = Specific_Heat(T_b,X_b);
e = 0.1;
f = e;
g = 0.01;
%i = 1; % This is moved to later
k = 0;
l = 100;
m = k;
n = l;
T = []; % This is new
for j=1:3
i = 1; % Moved from earlier
Ttemp = []; % This is new
for T_f = k:e:l
C_pf = Specific_Heat(T_f,X_f);
a = M_f*C_pf*(T_f-T_cw);
for T_o = m:f:n
b = M_d*C_pd*(T_d-T_o) + M_b*C_pb*(T_b-T_o);
if abs(a-b)<g
Ttemp(1,i) = T_f; % This has been renamed
Ttemp(2,i) = T_o; % This has been renamed
i=i+1;
end
end
end
T = [T, Ttemp]; % This is new
k = min(T(1,:));
l = max(T(1,:));
m = min(T(2,:));
n = max(T(2,:));
e = e/10;
f = f/10;
g = g/10;
end
Daniel Shub on 23 Nov 2011