Why is assignment with RedefinesParen so slow
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
LR
el 2 de Oct. de 2023
Comentada: James Lebak
el 3 de Oct. de 2023
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 comentarios
Respuesta aceptada
Matt J
el 2 de Oct. de 2023
Editada: Matt J
el 2 de Oct. de 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 comentarios
James Lebak
el 3 de Oct. de 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.
Más respuestas (0)
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!