Why is assignment with RedefinesParen so slow
6 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I want to make a class that wraps around an array, so I tried matlab.mixin.indexing.RedefinesParen to allow interfacing with the object as if it were an array. I'm finding that assigning to the wrapped array is typically 40-80x slower than regular assignment to an array. Here is a simple test class:
classdef TestCustomParen < matlab.mixin.indexing.RedefinesParen
properties
X
end
methods
function obj = cat(dim,varargin)
obj.X = cat(dim,varargin{:});
end
function sz = size(obj)
sz = size(obj.X);
end
end
methods(Static)
function obj = empty
obj = TestCustomParen;
end
end
methods(Access=protected)
function x = parenReference(obj, indexOp)
x = obj.X(indexOp.Indices{1});
end
function obj = parenAssign(obj,indexOp,varargin)
obj.X(indexOp.Indices{1}) = varargin{1};
end
function n = parenListLength(obj,indexOp,ctx)
n = listLength(obj.X,indexOp(3:end),ctx);
end
function obj = parenDelete(obj,indexOp)
obj.X.(indexOp) = [];
end
end
end
I'm not too concerned with what all the implementations are doing, just focsuing on parenAssign here.
And the timing script:
x = TestCustomParen;
tic
for ind = 1:1e4
x(ind) = rand;
end
toc
y = [];
tic
for ind = 1:1e4
y(ind) = rand;
end
toc
And the result:
Elapsed time is 0.085126 seconds.
Elapsed time is 0.001309 seconds.
(It seems I can't actually run this code in the post)
I also tried a version of this where the arrays are both pre-allocated, and in that case the difference becomes even more dramatic (more than 100x slowdown).
Is this slowdown just due to the overhead of accessing indexOp and opening cells? Is is possible to get this sort of behavior in a performant way? The documentation says overriding subsref is no longer recommended, but would that be faster?
0 Kommentare
Akzeptierte Antwort
Matt J
am 2 Okt. 2023
Bearbeitet: Matt J
am 2 Okt. 2023
Here is the proper way to time the operations. The difference isn't that big.
x = TestCustomParen;
x.X=rand(500);
y=x.X;
a=rand;
timeit(@()assig(x,a))\timeit(@()assig(y,a)),
timeit(@()Assig(x,a))\timeit(@()Assig(y,a)),
function assig(z,a)
z(1)=a;
end
function Assig(z,a)
z(:)=a;
end
12 Kommentare
James Lebak
am 3 Okt. 2023
In 23b we made significant improvements to dot-indexing performance. On my machine I see your original code running about 2x faster in 23b versus 23a, and my suspicion is that those improvements are probably the cause.
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Matrix Indexing finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!