number - tipo de dato byte c#
Agregue dos o más matrices de bytes en C# (8)
¿Ha enseñado sobre el uso de List o ArrayList en lugar de un Array? Con estos tipos, pueden crecer o encogerse y agregarse a través de InsertRange
¿Hay una forma mejor (ver más abajo) de agregar matrices de dos bytes en C #?
Pretendiendo que tengo el control completo, puedo hacer que la primera matriz de bytes sea lo suficientemente grande como para mantener la segunda matriz de bytes al final y usar la función Array.CopyTo . O puedo hacer un bucle sobre bytes individuales y hacer una asignación.
¿Hay mejores maneras? No puedo imaginarme haciendo algo como convertir las matrices de bytes en una cadena y unirlas y convertirlas de nuevo sería mejor que cualquiera de los métodos anteriores.
En términos de mejor / mejor (en orden):
- Lo más rápido
- Menor consumo de memoria RAM
Una restricción es que debo trabajar en el marco .NET 2.0.
Las dos opciones recomendadas son MemoryStream y BlockCopy. He ejecutado una prueba de velocidad simple de 10,000,000 bucles 3 veces y obtuve los siguientes resultados:
Promedio de 3 carreras de 10,000,000 bucles en milisegundos:
- BlockCopy Time: 1154 , con un rango de 13 milisegundos
- MemoryStream GetBuffer Time: 1470, con un rango de 14 milisegundos
- MemoryStream ToArray Time: 1895, con un rango de 3 milisegundos
- CopyTo Time: 2079, con un rango de 19 milisegundos
- Byte por byte Tiempo: 2203, con un rango de 10 milisegundos
Resultados de la lista <byte> AddRange sobre 10 millones de bucles: Lista <byte> Tiempo: 16694
Consumo de RAM relativo (1 es la línea de base, más alto es peor):
- Byte por byte: 1
- BlockCopy: 1
- Copiar a: 1
- MemoryStream GetBuffer: 2.3
- MemoryStream ToArray: 3.3
- Lista <byte>: 4.2
La prueba muestra que, en general, a menos que esté haciendo muchas copias de bytes [ que yo soy ], mirar las copias de bytes no vale la pena [por ejemplo, 10 millones de ejecuciones que producen una diferencia de hasta 1.1 segundos].
¿Necesita que la salida sea realmente una matriz de bytes?
Si no, puede crearse un "cursor inteligente" (que es similar a lo que hace LINQ): Cree un <Ente> de IEnumerator personalizado que primero itere la primera matriz, y simplemente continúe en la segunda sin interrupción.
Esto funcionaría en el marco 2.0 de forma rápida (ya que la unión de matrices prácticamente no tiene costo) y no utiliza más RAM de la que ya consumen las matrices.
Cree un nuevo MemoryStream pasando al constructor un búfer que sea exactamente del tamaño del fusionado. Escriba los arreglos individuales y, finalmente, utilice el búfer:
byte[] deadBeef = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF};
byte[] baadF00d = new byte[] { 0xBA, 0xAD, 0xF0, 0x0D};
int newSize = deadBeef.Length + baadF00d.Length;
var ms = new MemoryStream(new byte[newSize], 0, newSize, true, true);
ms.Write(deadBeef, 0, deadBeef.Length);
ms.Write(baadF00d, 0, baadF00d.Length);
byte[] merged = ms.GetBuffer();
Muchas de las funciones de E / S de bajo nivel en .NET toman arreglos y compensaciones de bytes. Esto se hizo para evitar copias innecesarias. Asegúrese de que realmente necesita la matriz combinada si esto es sensible al rendimiento, de lo contrario, solo use buffers y compensaciones.
Otra opción, aunque no lo he probado para ver cómo funciona en términos de velocidad y consumo de memoria, el enfoque de LINQ sería:
byte[] combined = bytesOne.Concat(bytesTwo).Concat(bytesThree).ToArray();
... donde bytesOne, bytesTwo y bytesTree son matrices de bytes. Dado que Concat usa la ejecución diferida, esto no debería crear ningún arreglo intermedio, y no debería duplicar los arreglos originales hasta que construya el arreglo final combinado al final.
Edición: LINQBridge le permitirá usar LINQ-to-Objects (de lo que es un ejemplo) en el marco 2.0. Entiendo que no quieres depender de esto, pero es una opción.
Quieres BlockCopy
Según esta publicación del blog , es más rápido que Array.CopyTo.
Si tiene matrices en las que el tamaño cambiará de vez en cuando, probablemente esté mejor usando una List<T>
en primer lugar. Luego puedes simplemente llamar al método AddRange()
de la lista.
De lo contrario, Array.Copy () o Array.CopyTo () son tan buenos como cualquier otra cosa que pueda ver.
Su primera opción de hacer que la primera matriz sea lo suficientemente grande como para contener la segunda matriz y usar Array.CopyTo termina siendo aproximadamente la misma que iterar manualmente sobre cada elemento y hacer la asignación. Array.CopyTo () solo lo hace más conciso.
La conversión a la cadena y la vuelta a la matriz será terriblemente lenta en contraste con lo anterior. Y probablemente usaría más memoria.
También podría utilizar un enfoque con un MemoryStream. Supongamos que b1 y b2 son matrices de dos bytes, puede obtener una nueva, b3, utilizando MemoryStream de la siguiente manera:
var s = new MemoryStream();
s.Write(b1, 0, b1.Length);
s.Write(b2, 0, b2.Length);
var b3 = s.ToArray();
Esto debería funcionar sin LINQ y, de hecho, es bastante más rápido.