7
votes

Quel est le moyen le plus rapide d'ajouter un élément à un tableau?

Ceci est une question de suivi à Comment comment Pour ajouter un élément à un tableau dans Matlab? Cette question adressée comment em> pour ajouter un élément à un tableau. Deux approches sont discutées là-bas:

A(end+1) = elem;


1 commentaires

Je viens de rencontrer la question suivante, une réponse qui s'adresse aux problèmes de performance: Stackoverflow.com/Questtions/16188058/...


3 Réponses :


4
votes

La deuxième approche ( A (fin + 1) = elem code>) est plus rapide

en fonction des repères ci-dessous (exécuté avec le TIMOIT CODE> Benchmarking Fonction de fichier Exchange ), la deuxième approche ( a (fin +1) = elem code>) est plus rapide et devrait donc être préféré. P>

intéressant, cependant, l'écart de performance entre les deux approches est beaucoup plus étroite dans les anciennes versions de Matlab que dans des versions plus récentes fortes>. p>

r2008a h3>

Entrez l'image Description ici P>

R2013A H3>

 Benchmark Run dans matlab R2013A P>

Code de référence H2>
function benchmark

    n = logspace(2, 5, 40);
    % n = logspace(2, 4, 40); 
    tf = zeros(size(n));
    tg = tf;

    for k = 1 : numel(n)
        x = rand(round(n(k)), 1);

        f = @() append(x);
        tf(k) = timeit(f);

        g = @() addtoend(x);
        tg(k) = timeit(g);
    end

    figure
    hold on
    plot(n, tf, 'bo')
    plot(n, tg, 'ro')
    hold off
    xlabel('input size')
    ylabel('time (s)')
    leg = legend('y = [y, x(k)]', 'y(end + 1) = x(k)');
    set(leg, 'Location', 'NorthWest');
end

% Approach 1: y = [y, x(k)];
function y = append(x)
    y = [];
    for k = 1 : numel(x);
        y = [y, x(k)];
    end
end

% Approach 2: y(end + 1) = x(k);
function y = addtoend(x)
    y = [];
    for k = 1 : numel(x);
        y(end + 1) = x(k);
    end
end


0 commentaires

2
votes

Comment de cela? XXX

Pour ma machine, cela donne les horaires suivants: xxx

L'orientation du vecteur ne fait pas semblent compter que beaucoup, mais la deuxième approche concerne un facteur 100 plus rapide sur ma machine.


5 commentaires

Vous devez utiliser TimeIt au lieu de TIC / TOC , cependant; Ce dernier n'est pas un moyen fiable de mesurer le temps d'exécution .


Merci pour votre suggestion. Étrangement, pour moi, le speed-up est toujours un facteur ~ 100, tandis que l'exécution de votre code ne donne une accélération d'un facteur 6.


Hmm ... bizarre. Je vais essayer de courir votre référence sur ma machine et je ferai rapport. +1 de toute façon.


@Jubobs: vraiment? C'est bizarre, rng est la fonction qui contrôle la sortie de rand , randi et randn , et est un noyau Fonction MATLAB. Je l'ai inclus dans mon code (R2014B) pour vous assurer que tous les horaires utilisaient le même vecteur aléatoire. Peut-être utilisez-vous une ancienne version de MATLAB dans laquelle la commande n'est pas disponible, vous pouvez utiliser des syntaxes anciennes trouvées ici: nl.mathworks.com/help/matlab/math/...


Je n'avais que votre code dans Matlab R2008A; Peut-être que ce n'était pas encore là. Je vais essayer dans une version plus récente.



1
votes

En plus de la méthode de croissance rapide indiquant ci-dessus (c'est-à-dire A (k + 1) ), vous pouvez également obtenir une augmentation de vitesse d'augmenter la taille de la matrice par certains multiples, de sorte que les allocations Devenez moins à mesure que la taille augmente.

sur mon ordinateur portable à l'aide de R2014B, un doublement conditionnel de la taille entraîne une augmentation de 6 vitesses: xxx

dans une application réelle , la taille de a serait limitée à la taille nécessaire ou aux résultats non remplis filtrés d'une manière ou d'une autre.


Le code Pour la fonction SO est ci-dessous. Je note que je suis passée à cos (k) car, pour une raison quelconque inconnue, il existe une grande différence de performance entre rand () et rand (1, 1) sur ma machine. Mais je ne pense pas que cela affecte trop le résultat. xxx


2 commentaires

Oui, bon point (+1). Le problème est que, parfois, vous voulez vraiment ajouter un seul élément sans avoir à couvrir les zéros.


Vrai. Connaître la taille finale de la matrice est la meilleure pratique, à mon avis. Mais puisque la question demandait comment développer efficacement une matrice, j'ai pensé que la taille finale de la matrice était inconnue. J'ai obtenu cette technique de regarder une conférence discutant de la manière dont Python augmente les listes de temps de constante-ish sans savoir quelle sera la taille de la matrice.