"Effectively" create subclass of cell array to eliminate overhead when constructing large object arrays?
Show older comments
I'm trying to create a quaternion class, both as an attempt to better understand MATLAB (and programming in general, which I'm relatively limited in), and ultimately to use in a project for an engineering course—something like this, maybe, but at an undergrad engineering student's level of programming sophistication ;)
The issue I've run into is that constructing large arrays of these quaternion objects (100,000+ elements) takes quite a while. I'm not sure how large the arrays I'll need to use will be in practice, so it might be a non-issue, but I'd like it to be efficient in a general case if possible.
Currently, my class has one property ("Q"), which is a 4 element array containing the quaternion's coefficients. To assign this, my constructor takes in a numeric array, chops it up into a cell array ("coefs") where the element at each index is the quaternion coefficients for the corresponding index of the quaternion object array ("qtr"), then I do:
[qtr(:).Q] = coefs{:};
This is really slow (around 2 seconds for 1,000,000 elements on my computer). From browsing FAQs and using the profiler, it seems like basically all the time is going to overhead of accessing the .Q property at each array element. Chopping up the cell array (mat2cell) isn't crazy fast, but it only happens when constructing quaternions. The property accessing overhead is a concern because, when doing operations on quaternion arrays, I need to access all the properties of each input and construct a whole new quaternion for output, accessing properties all along the way. For example, the substantial part of my addition function is:
% Perform addition via cell array
q1Coefs = {q1(:).Q};
q2Coefs = {q2(:).Q};
qNewCoefs = cellfun(@plus,q1Coefs,q2Coefs,'Uni',0);
% Create & populate output quaternion
qNew(r1,c1) = quaternion;
[qNew(:).Q] = qNewCoefs{:};
I like using the cell functions because it's visually cleaner and I've been led to believe MATLAB might handle this method better than alternatives with for loops (I did try using parfor, but couldn't get it to improve performance). I compared the time it takes to create and add similarly-sized quaternions using my class with that class from the file exchange (which I assume is reasonably optimized) and they're just about the same. All this has made me wonder:
Am I able to "cut out the middleman" of converting to cell arrays and accessing the .Q property by somehow defining my quaternion arrays to be cell arrays of the coefficients? I know I can't create a subclass of cell arrays, but does that completely preclude me from the benefits of classes (operator overloading in particular, MATLAB "knowing" what a quaternion is) if I decide to define the quaternions as cell arrays? I could make my .Q property the cell array I want, but then all of my quaternion arrays will be considered "1x1 quaternions", and concatenating them becomes less useful. I'd like to avoid simply having a suite of functions that require the input to be of the form I want.
Any advice (or explanations on why what I want isn't possible) is appreciated! My classdef file is attached, which currently just does addition, subtraction, and a neat display method for individual quaternions.
2 Comments
Image Analyst
on 6 Mar 2022
Cell arrays are very inefficient expecially when they get very large. Here's an example for an array 1000 times smaller than yours:
N = 1000
A = ones(N,N);
ca = cell(N, N);
for k = 1 : numel(ca)
ca{k} = A(k);
end
whos
Name Size Bytes Class Attributes
A 1000x1000 8000000 double
N 1x1 8 double
ca 1000x1000 112000000 cell
Look at the Bytes used for each. The cell array takes up 14 times as much memory.
Try to avoid cell arrays if at all possible. Use tables or regular numerical arrays instead.
Aaron Becker
on 6 Mar 2022
Edited: Aaron Becker
on 6 Mar 2022
Accepted Answer
More Answers (0)
Categories
Find more on Customize Object Indexing 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!