How to make my algorithm work faster
Show older comments
Hello everyone! Sorry if this is a problem with a very simple solution but I'm quite new to matlab and to programming. I have an algorithm in which I need merge 2 very big tables. I need to do this merge 3 times and each time is a little bit different. I made 3 scripts for each merge with a while in which I compare the value on the first column in both tables and i need to add the lower one plus some values in the new table. This takes a lot and i would be really thankful if someone could help me make it work faster. This is my first question on this forum and any tips about how to create a question would be helpful as well.
6 Comments
José-Luis
on 18 Aug 2017
Please post a minimum working example illustrating your problem.
Otherwise, all we can do is give generic advice and are reduced to guessing what your problem is, which is rather ineficient.
Sometimes, processes take time, this is unavoidable if your operations are large enough.
Urs Grigore
on 18 Aug 2017
Edited: Urs Grigore
on 18 Aug 2017
Adam
on 18 Aug 2017
doc profile
is what you should use before you do any speedup work on code. Otherwise it is total guesswork as to what is slow and what isn't.
First piece of advice:
Use comments. Lots of comments.
Yes, the code is ugly. It's normal for beginners. You're clearly not aware of the various look-up functions in matlab such as find, ismember, etc.
Your code can certainly be improved, for example, the loop:
while Tabel1.Var1(kTabel1)>Tabel2.Var1(kTabel2)
kTabel2=kTabel2+1;
end
can be replaced by
ktabel2 = find(Tabel2.Var1 <= Tabel1.Var1(1), 1); %find 1st element of Tabel2.Var1 less than or equal to Tabel1.Var1(1)
Similarly, the next loop can be replaced by a one liner:
ktabel1 = find(Tabel1.Var1 >= Tabel2.Var1(ktabel2), 1);
After that, I've given up trying to understand what it is you're doing due to the lack of comments. So Please explain in details what it is you're trying to achieve. Most likely most of your code can be ditched and replaced with a more efficient version that uses matlab built-in functions.
Other pieces of advice:
- Avoid misleading names. Your Tabel3 is clearly not a table but a plain matrix.
- Use meaningful names for your variables and table columns. The advantage of tables is that columns can have names that explain what it is they hold. Var1 is pretty useless for that.
- prefer true, false instead of 0, 1 for flags. Personally, I prefer if ~ok to if ok == false or if ok == 0. My version reads as if not ok which better express your intent.
Urs Grigore
on 23 Aug 2017
Stephen23
on 23 Aug 2017
" I only worked in c++ and a little bit in python and i'm having some issues getting used to Matlab"
Forget everything you know about C++ and Python: they work in totally different ways to MATLAB.
The introductory tutorials are the recommended way to learn important MATLAB concepts:
Answers (2)
Addressing the field of the table costs time. Because you read only in .Var1 in both tables, you can use a temporary variable efficiently:
T1 = Table1.Var1;
T2 = Table2.Var1;
The term "Table" occurs very frequently in the code such that is looks rather redundant. The naming of variables is a question of taste, but everything which improves the readability might be an advantage for understanding the code. Sometimes a patterns in the code get clear with a better readability. I prefer "k1" instead of "kTable1".
Replace:
kTabel1 = 1;
kTabel2 = 1;
if Tabel1.Var1(1)>Tabel2.Var1(1)
while Tabel1.Var1(kTabel1)>Tabel2.Var1(kTabel2)
kTabel2=kTabel2+1;
end
kTabel1=kTabel1+1;
end
by:
k1 = 1;
k2 = 1;
if T1(1) > T2(1)
k2 = find(T1(1) > T2, 1);
k1 = 2;
end
In opposite to the first version of your code, Table3 is not pre-allocated before the loop in the last version. This is slow down the processing substantially. The iterative growing of arrays requires an exponentially growing amount of resources. This was better - except for the name:
Tabel3 = zeros(hTabel1+hTabel2+5, 3);
I have only a few experiences with working in tables. I guess the creation of a double matrix is faster. Then you can create the table after the loop in one step.
"cell" is an important builtin function. Shadowing it by a local variable is not an error, but confusing.
cell = {time, Tabel1.Var3(kTabel1-1)*Tabel2.Var3(kTabel2-1), ...
Tabel1.Var5(kTabel1-1)*Tabel2.Var5(kTabel2-1)};
Tabel3(kTabel3,:)=cell;
Or I assume this is faster:
Tabel3(k3, 1) = time;
Tabel3(k3, 2) = T1V3(k1 - 1) * T2V3(k2 - 1);
Tabel3(k3, 3) = T1V5(k1 - 1) * T2V5(k2 - 1);
With "T1V3" was set as shortcut to "Table1.Var3".
Instead of:
ok = false;
if xyz
ok=true;
end
if ~ok && abc
ok=true;
end
if ~ok ...
you can write:
if xyz
...
elseif abc
...
elseif ...
This will not reduce the runtime a lot, but it is nicer to read.
2 Comments
Urs Grigore
on 23 Aug 2017
Edited: Urs Grigore
on 23 Aug 2017
Jan
on 23 Aug 2017
I guess I cannot do that.
Cannot do what? A pre-allocation is essential.
Note that it is much easier to improve your code, when we can run it. So provide some representative inputs.
Urs Grigore
on 24 Aug 2017
0 votes
Categories
Find more on Tables in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!