Optimizing Algorithmic Coding: Essential Do's and Don'ts
Written on
Chapter 1: Introduction to Algorithm Coding
In today’s tech-driven world, many desk workers, especially programmers, routinely write code. While most developers focus on creating applications and websites, this blog targets those who write algorithms. However, several insights shared here may apply broadly to programming disciplines, so feel free to take notes as you read.
This section provides insights into improving coding practices for algorithms.
Section 1.1: Minimize Loop Usage
When faced with repetitive tasks, your instinct might be to implement a loop. While loops can be effective, they should be avoided when possible.
Consider a scenario in MATLAB where you have a vector containing 21,600 entries. Every set of 180 entries represents a two-dimensional image solution. To mesh this data into a visual representation, you need to reshape the vector into a 180x120 matrix. A common approach using nested loops looks like this:
rho = zeros(N_chi*N_Knoten, N_xi);
for K1 = 1:N_xi
for K2 = 1:N_chi*N_Knoten
rho(K2, K1) = result((K1-1)*N_chi*N_Knoten + K2);end
end
Here, we initialize the rho matrix and populate it with elements from result. Timing this snippet shows it takes 0.181187 seconds. While this may seem acceptable, optimization should always be a priority.
A more efficient solution utilizes MATLAB’s reshape function:
rho = reshape(result, N_chi*N_Knoten, N_xi);
This command condenses the previous six lines into one, achieving the same result in only 0.033776 seconds—a significant reduction of 81.36%.
Furthermore, unnecessary loops can often be avoided when processing arrays or vectors. For instance, consider multiplying a vector with a scalar or another vector. Instead of iterating through each element, use built-in operations for element-wise multiplication or division, which are available in both MATLAB and Python.
The following common loop checks vector elements against a condition:
for i = 1:N_xi
if (eigsA > 0)
rhs(i) = -Q*delt_xi*f(i)*eigsA(i);else
rhs(i) = Q*delt_xi*f(i)*eigsA(i);end
end
This approach is inefficient. Instead, you could rewrite the code to:
rhs(eigsA > 0) = -Q*delta_xi*f.*eigsA;
rhs(eigsA < 0) = Q*delta_xi*f.*eigsA;
This not only shortens the code but also enhances performance.
Section 1.2: Eliminate Redundant Calculations
In some cases, loops are unavoidable, such as when dealing with transient problems that require time iterations. If you find yourself needing to create a time loop, strive to remove unnecessary computations from within it. For example:
u = rhs - (GDR + G_glob)*u;
In this instance, the matrices GDR and G_glob remain constant throughout the loop, as does the vector rhs. Instead of recalculating these during each iteration, you can extract them outside the loop:
A = GDR + G_glob;
for i = 1:tsteps
u = rhs - A*u;
end
While this may consume more RAM, it can significantly reduce computation time, especially when working with extensive time steps.
Chapter 2: Importance of Documentation
Documenting your code is crucial for any programmer, particularly in collaborative environments. As someone relatively new to coding and MATLAB, I found it challenging to decipher the code written by others, especially when it lacked comments.
During my Ph.D. journey, I was introduced to codebases from two master's students that were well-structured but inadequately commented. This lack of documentation made it difficult for me to grasp the algorithms, despite their efficiency.
Consider the following uncommented MATLAB function:
function [eigs_A, R] = DiagonalDrift(Ky)
Kpy = Ky + 1;
a = 0; b = +1i/2; c = -1i/2; factor = sqrt(b*c);
eigs_A = zeros(Kpy - 1, 1);
R = zeros(Kpy - 1);
norm_R = 0;
k = 1:Ky;
for j = 1:Kpy - 1
eigs_A(j) = (a - sign(imag(c)) * 2*factor*cos(pi*j/((Kpy - 1) + 1)));
R(:, j) = (b/c).^(k/2).*sin(k*pi*j/Kpy);
norm_R = norm_R + R(1, j)^2;
end
R = 1/sqrt(norm_R) * R;
Lambda = diag(eigs_A);
end
Adding comments can clarify its purpose and functionality:
function [eigs_A, R] = DiagonalDrift(Ky)
% purpose: compute the eigenvalues and eigenvectors analytically
% Initialize number of element faces Kpy and constants
Kpy = Ky + 1;
a = 0; b = +1i/2; c = -1i/2; factor = sqrt(b*c);
% Initialize empty vector and matrix for eigenvalues and eigenvectors
eigs_A = zeros(Kpy - 1, 1);
R = zeros(Kpy - 1);
norm_R = 0;
k = 1:Ky;
for j = 1:Kpy - 1
% Calculate eigenvalues
eigs_A(j) = (a - sign(imag(c)) * 2*factor*cos(pi*j/((Kpy - 1) + 1)));
% Calculate matrix of eigenvectors
R(:, j) = (b/c).^(k/2).*sin(k*pi*j/Kpy);
norm_R = norm_R + R(1, j)^2;
end
R = 1/sqrt(norm_R) * R;
Lambda = diag(eigs_A);
end
With added comments, users can quickly grasp the code’s functionality without needing to dissect each line.
Section 1.3: Efficient Memory Usage
When coding algorithms, managing RAM and execution time is vital. In many cases, matrices hold a large number of zero values. Even storing zero occupies RAM. Thus, utilizing the sparse keyword when defining matrices in MATLAB and Python is essential for conserving memory.
Traditional methods might initialize a matrix with zeros, but sparse matrices are genuinely empty, only populated with values as needed. For example, in a square tridiagonal matrix, a sparse matrix retains values only on the main and adjacent diagonals, while a zeros matrix holds zeros for every other element.
While sparse matrices might slow down operations within loops, strategically placing them outside of loops can lead to significant RAM savings, allowing for larger matrices to be used.
In conclusion, these tips reflect some valuable lessons I’ve learned during my recent coding experiences in MATLAB. I hope you find them beneficial!
Thank you for reading. If you enjoyed this content, a clap 👏 would be appreciated! Don’t forget to follow me on Medium and Twitter for more insights. For feedback or collaboration inquiries, feel free to contact me via DM or email at [email protected]. Comments are always welcome!
The first video titled "How to understand (almost) any algorithm - Inside code - YouTube" provides an insightful overview of algorithms, making complex concepts easier to grasp.
The second video, "Algorithms Explained for Beginners - How I Wish I Was Taught - YouTube," is perfect for those just getting started in programming and algorithm design.