11
votes

Un moyen extrêmement rapide de cloner les valeurs d'une matrice déchiquetée dans un deuxième tableau?

Je travaille actuellement sur une application responsable du calcul des permutations aléatoires d'une matrice déchiquetée.

Actuellement, la majeure partie de l'époque dans l'application est consacrée à la copie de la matrice dans chaque itération (1 million d'itérations au total). Sur mon système actuel, l'ensemble du processus prend 50 secondes à compléter, 39 de ces secondes passées au clonage de la matrice. P>

Ma routine de clonage de matrice est la suivante: P>

    public static int[][] CopyArray(this int[][] source)
    {
        int[][] destination = new int[source.Length][];
        // For each Row
        for (int y = 0; y < source.Length; y++)
        {
            // Initialize Array
            destination[y] = new int[source[y].Length];
            // For each Column
            for (int x = 0; x < destination[y].Length; x++)
            {
                destination[y][x] = source[y][x];
            }
        }
        return destination;
    }


1 commentaires

Avez-vous essayé d'utiliser des tableaux multidimensionnels au lieu de blackged, c'est-à-dire statique int [] au lieu de statique int [] [] ?


4 Réponses :


0
votes

Que diriez-vous de sérialiser / de désérialiser le tableau, si vous utilisez des flux de mémoire et une sérialisation binaire, je pense que cela devrait être assez rapide.


1 commentaires

La sérialisation est probablement des ordres de magnitude plus lentes que sa mise en œuvre actuelle.



1
votes

Vous pouvez utiliser array.clone pour la boucle interne: xxx

Une autre alternative pour la boucle interne est tampon.blockcopy , Mais je n'ai pas mesuré sa performance contre array.clone - peut-être que c'est plus rapide: xxx

EDIT: tampon.blockcopy prend le numéro pour octets à copier pour le paramètre de comptage, pas le nombre d'éléments de tableau.


2 commentaires

J'ai essayé votre première solution. Malheureusement, il ne fait que raser quelques secondes de tout le temps d'exécution. Je vais essayer votre deuxième solution.


Votre deuxième option est assez comparable à celle du premier. Seulement rasé une seconde ou deux hors du temps total par rapport à ma méthode d'origine.



25
votes

L'un de ceux-ci devrait fonctionner pour vous. Ils fonctionnent tous les deux à peu près au même temps et sont tous deux beaucoup plus rapides que votre méthode.

// 100 passes on a int[1000][1000] set size

// 701% faster than original (14.26%)
static int[][] CopyArrayLinq(int[][] source)
{
    return source.Select(s => s.ToArray()).ToArray();
}

// 752% faster than original (13.38%)
static int[][] CopyArrayBuiltIn(int[][] source)
{
    var len = source.Length;
    var dest = new int[len][];

    for (var x = 0; x < len; x++)
    {
        var inner = source[x];
        var ilen = inner.Length;
        var newer = new int[ilen];
        Array.Copy(inner, newer, ilen);
        dest[x] = newer;
    }

    return dest;
}


1 commentaires

Un tel soulagement pour moi de trouver ceci: BTW, il semble assez facile de l'étendre à plus de dimensions: Retour Source.Sélectionnez (S => S.Sélectionnez (P => P.TOTAARRAY ()). TOARRAY ()). TOARRAY ()). TOARRAY ();



0
votes

Le moyen plus rapide de copier des objets n'est pas de les copier du tout - avez-vous considéré cette option? Si vous avez juste besoin de générer des permutations, vous n'avez pas besoin de copier des données sur chacune d'elles - changez simplement la matrice. Cette approche ne fonctionnera pas bien si vous devez continuer à obtenir des résultats des appels précédents. En tout cas examiner votre code pour voir si vous ne copiez pas les données plus de fois que vous devez.


1 commentaires

J'ai besoin d'une copie séparée de la matrice, car chaque permutation doit avoir un ensemble de travail original.