Vectorized code slower than loops
0 Comments
Accepted Answer
More Answers (5)
0 Comments
0 Comments
2 Comments
Hi @Alessandro,
Please see “Recommendations for Performance Improvement” below
1. Avoid Large Temporary Arrays: Instead of using `repelem`, consider avoiding temporary arrays altogether. You can directly compute values without expanding them into larger matrices.
2. Use Logical Indexing: If applicable, replace some array operations with logical indexing or direct computations that avoid unnecessary replication of data.
3. Preallocate Arrays Wisely: Ensure that all arrays are preallocated appropriately without excessive resizing during iterations.
4. Parallel Processing: If your MATLAB version supports it, consider using parallel processing capabilities (like `parfor`) to distribute computations across multiple cores.
5. Profile the Code: Use MATLAB's built-in profiler (`profile on`, `profile viewer`) to identify bottlenecks in your code execution and focus optimization efforts on those areas.
6. Consider Built-in Functions: Some operations might have optimized built-in functions that can perform better than custom implementations.
Here's a modified version of Method 2 that addresses some of these issues:
disp('Optimized Method 2') tic V2 = zeros(n_a, n_z); Policy2 = zeros(n_a, n_z); % Changed to zeros instead of ones for z_c = 1:n_z EVz = V_next * pi_z(z_c,:)'; % Directly calculate entireRHS without expanding for a_c = 1:n_a entireRHS = RetMat(:, a_c, z_c) + beta * EVz; [max_val, max_ind] = max(entireRHS); V2(a_c, z_c) = max_val; Policy2(a_c, z_c) = max_ind; end end % Reshape policy outputs as before Policy2_all = zeros(2, n_a, n_z); [d_opt, aprime_opt] = ind2sub([n_d, n_aprime], Policy2); Policy2_all(1,:,:) = d_opt; Policy2_all(2,:,:) = aprime_opt; toc
After implementing changes, it's crucial to profile the new version against both original methods to quantify performance improvements. Investigate other forms of vectorization such as `bsxfun` or implicit expansion features in newer MATLAB versions that might offer better performance with less memory overhead.
By following these strategies and continually iterating on your approach based on profiling results, you should be able to enhance the performance of your MATLAB code effectively.
2 Comments
Hi @Alessandro ,
To address the issues you're facing with your MATLAB code, I took care of the errors that you were facing and created a full, updated example that incorporates the optimization strategies while ensuring that array sizes are compatible. The goal was to enhance performance without generating errors. Below, I’ll define all necessary functions and parameters, using synthetic data to ensure the code is functional and correct.
% Define synthetic data n_a = 5; % Number of actions n_z = 3; % Number of states n_d = 4; % Number of dimensions in RetMat beta = 0.95; % Discount factor
% Generate synthetic RetMat RetMat = rand(n_d * n_a, n_z); % Random returns matrix pi_z = rand(n_z, n_z); % Random policy matrix (transition probabilities) V_next = rand(n_a, n_z); % Expected value for next period
% Initialize value and policy matrices V2 = zeros(n_a, n_z); Policy2 = zeros(n_a, n_z);
% Optimization Process disp('Optimized Method 2') tic
for z_c = 1:n_z EVz = V_next(:, z_c); % Keep EVz as [n_a, 1]
for a_c = 1:n_a entireRHS = RetMat((a_c-1)*n_d + (1:n_d), z_c) + beta * EVz(a_c); [max_val, max_ind] = max(entireRHS); V2(a_c, z_c) = max_val; Policy2(a_c, z_c) = max_ind; end end
% Reshape policy outputs Policy2_all = zeros(2, n_a, n_z); [d_opt, aprime_opt] = ind2sub([n_d, n_a], Policy2); Policy2_all(1,:,:) = d_opt; Policy2_all(2,:,:) = aprime_opt;
toc
% Display results disp('Value Function:'); disp(V2); disp('Policy Indices:'); disp(Policy2);
Please see attached.
In the above provided modified code, following are the explanations of code below.
1. Array Size Compatibility: The original issue arose because `EVz` was not conformable with `RetMat`. In this update, I ensured that `EVz` is extracted correctly as a column vector corresponding to the current action `a_c`. The indexing of `RetMat` was adjusted to ensure it aligns properly with the number of dimensions.
2. Avoiding Large Temporary Arrays: By directly computing values without creating unnecessary large matrices (like `repelem`), minimize memory usage and improve computational efficiency.
3. Logical Indexing: The revised indexing within the loops ensures that we avoid unnecessary data replication.
4. Preallocation: maintain preallocation practices with `V2` and `Policy2`, which helps prevent dynamic resizing during iterations.
5. Profiling and Performance Monitoring: After implementing these changes, it is recommended to use MATLAB's profiler (`profile on`, `profile viewer`) to assess performance improvements and identify any remaining bottlenecks.
By following these modifications and employing profiling tools, you should be able to significantly enhance the performance of your MATLAB code while avoiding errors associated with array size mismatches.
See Also
Categories
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!