Ajouter deux ou plusieurs tableaux d'octets en C#
Est-il un des meilleurs (voir ci-dessous) de manière à ajouter deux tableaux d'octets en C#?
Prétendant j'ai un contrôle complet, je peux faire le premier tableau d'octets suffisamment grand pour contenir le deuxième tableau d'octets à la fin et l'utilisation de la Tableau.CopyTo fonction. Ou je peut faire une boucle sur chacun des octets et de réaliser une cession.
Sont t-il de meilleures façons de faire? Je ne peux pas imaginer faire quelque chose comme la conversion de l'tableaux d'octets de la chaîne et de les rejoindre et de les convertir en retour serait mieux que ce soit la méthode ci-dessus.
En termes de meilleure/mieux (dans l'ordre):
- Plus rapide
- Moins de consommation de RAM
Une contrainte, c'est que je dois travailler dans le .NET framework 2.0.
Les deux choix sont recommandés MemoryStream et BlockCopy. J'ai l'exécution d'un simple test de vitesse de 10 000 000 de boucles 3 fois et a obtenu les résultats suivants:
Moyenne des 3 essais de 10 000 000 de boucles en millisecondes:
- BlockCopy Temps: 1154, avec une gamme de 13 millisecondes
- MemoryStream GetBuffer Temps: 1470, avec une gamme de 14 millisecondes
- MemoryStream ToArray Temps: 1895, avec une gamme de 3 millisecondes
- CopyTo Temps: 2079, avec une gamme de 19 millisecondes
- Octet-par-octet Temps: 2203, avec une portée de 10 millisecondes
Résultats de la Liste<byte> AddRange plus de 10 millions de boucles:
Liste<byte> Temps: 16694
Relative de la Consommation de RAM (1 est la base, plus élevé est le pire):
- Octet-par-octet: 1
- BlockCopy: 1
- Copie À: 1
- MemoryStream GetBuffer: 2.3
- MemoryStream ToArray: 3.3
- Liste<byte>: 4.2
Le test montre qu'en général, sauf si vous faites beaucoup de l'octet copies [qui je suis], à la recherche à l'octet copie ne vaut pas l'accent [par exemple, 10 millions de pistes ce qui donne une différence de plus de 1.1 secondes].
- Re: utilisation de la Mémoire de La meilleure façon de le savoir est d'utiliser un profileur de mémoire.
- Merci, j'ai utilisé le CLR Profiler pour obtenir les données de la mémoire. Oublié de l'exécuter en tant qu'administrateur, afin d'obtenir des résultats positifs qui a été retardé.
- double possible de la Meilleure façon de combiner deux ou plusieurs tableaux d'octets en C#
- stackoverflow.com/questions/415291/...
Vous devez vous connecter pour publier un commentaire.
Vous voulez BlockCopy
Selon ce blog il est plus rapide que la Matrice.CopyTo.
Vous pouvez également utiliser une approche avec un MemoryStream. Supposons que b1 et b2 sont deux tableaux d'octets, vous pouvez en obtenir un nouveau, b3, à l'aide de la MemoryStream de la manière suivante:
Cela devrait fonctionner sans LINQ et est en fait assez un peu plus vite.
Créer un nouveau MemoryStream passer dans le constructeur d'une mémoire tampon qui est exactement la taille de la fusion de l'un. Écrire l'individu tableaux, et puis, enfin, utiliser le tampon:
Beaucoup de bas-niveau I/O fonctions .NET des tableaux d'octets et les décalages. Cela a été fait pour empêcher inutile de copies. Assurez-vous que vous vraiment besoin de le tableau fusionné si cette performance est sensible, sinon il suffit d'utiliser les tampons et les décalages.
Une autre option, bien que je ne l'ai pas testé pour voir comment celui-ci réagira en termes de vitesse et de consommation de mémoire, l'approche de LINQ:
...où bytesOne, bytesTwo, et bytesThree sont des tableaux d'octets. Depuis Concat utilise l'exécution différée, cela ne devrait pas créer intermédiaire de tableaux, et il ne devrait pas dupliquer l'origine des tableaux jusqu'à ce qu'il construit la finale tableau fusionné à la fin.
Edit: LINQBridge vous permettra d'utiliser LINQ-to-Objets (ce qui est un exemple) dans le framework 2.0. Je comprends si vous ne voulez pas dépendre de cela, mais c'est une option.
Si vous avez des tableaux dont la taille change de temps en temps, vous êtes probablement mieux d'utiliser un
List<T>
en premier lieu. Ensuite, vous pouvez simplement appeler leAddRange()
méthode de la liste.Sinon, Tableau.Copier() ou d'un Tableau.CopyTo() sont aussi bon que n'importe quoi d'autre, vous êtes susceptible de voir.
Avez-vous appris à propos de l'utilisation de la Liste ou liste de tableaux au lieu d'un Tableau? Avec ces types de, ils peuvent augmenter ou de réduire et ajouter via InsertRange
Avez-vous besoin de la sortie en fait un tableau d'octets?
Si non, vous pouvez créer vous-même un "smart curseur" (qui est similaire à ce que LINQ n'): Créer un personnalisé IEnumerator<byte> qui sera la première à itérer le premier tableau, et il suffit de continuer sur la seconde sans interuption.
Ce serait le travail dans les framework 2.0 être rapide (en ce que l'assemblage des matrices a pratiquement pas de coût), et ne pas utiliser plus de RAM que les tableaux consomment déjà.
Votre première option de faire le premier tableau assez grand pour contenir le deuxième tableau, et à l'aide du Tableau.CopyTo finit par être à peu près le même que manuellement une itération sur chaque élément et de l'affectation. Tableau.CopyTo() ne fait que le rendre plus concis.
De la conversion à la chaîne et au retour à la matrice sera horriblement lent par contre. Et serait susceptible d'utiliser plus de mémoire.