j'ai donc essayé d'améliorer votre code un peu et vous pouvez voir les résultats ci-dessous:
%% My approach to solve the question (it has a slightly better runtime)
function c = myapproach(a, cells)
c = {a.b};
sz = [a.Size];
for i = 1:cells
c{i} = c{i}(1:sz(i));
end
end
Bien que cette n'évite pas la boucle for, il a un temps d'exécution légèrement meilleur. Les temps d'exécution (aux cellules = 50000) que j'ai eu étaient: @yourapproach = 0.0889, @myapproach = 0.0721, @rahnema1 = 0.2329
Ce qui suit est le code que j'ai utilisé pour résoudre ce problème. J'ai aussi apporté quelques améliorations au code que vous utilisez pour générer a
(Marqué par un commentaire)
function solveit()
cells = 50000;
maxVal = 40;
Sizes = randi(maxVal, 1, cells);
a(cells) = struct('Size', 0, 'b', []); %% Improved by preallocating a
for i = 1:cells
a(i).b = rand(1, maxVal); %% Improved by removing the unnecessary double loop
a(i).Size = Sizes(i);
end
fun1 = @() yourapproach(a, cells);
fun2 = @() myapproach(a, cells);
fun3 = @() rahnema1(a);
%% Show runtimes
timeit(fun1)
timeit(fun2)
timeit(fun3)
c1 = fun1();
c2 = fun2();
c3 = fun3();
%%Show approach equivalence
disp(isequal(c1, c2))
disp(isequal(c1, c3))
end
%% Your approach
function c = yourapproach(a, cells)
c = cell(1, cells);
for i = 1:cells
sz = a(i).Size;
c{1,i} = a(i).b(1:sz);
end
end
%% Approach mentioned by rahnema1
function c = rahnema1(a)
cc = struct2cell(a);
sz = [cc{1:2:end}];
sz = [sz;40-sz];
dat = [cc{2:2:end}];
c = mat2cell(dat, 1, sz(:));
c = c(1:2:end);
end
Edit: J'ajoute l'approche arrayfun
, mais il est au moins 10 fois plus lent que la boucle for
function c = newapproach(a)
sz = [a.Size];
c = arrayfun(@(x, y) x.b(1:y), a, sz, 'UniformOutput', false);
end
Quel est le problème avec la solution actuelle? – excaza
La solution actuelle utilise une boucle for que je voudrais éviter car 'cells' est habituellement autour de 50000. – evolved
Une solution rapide peut être de créer un fichier mex. – m7913d