c# - tamaño - ¿Cómo poner a cero rápidamente una matriz?
recorrer matriz c# (6)
Actualmente lo estoy haciendo en un ciclo for, y sé que en C está la API ZeroMemory, sin embargo, eso no parece estar disponible en C #. Tampoco existe el Array.fill equivalente de Java. Me pregunto si hay una manera más fácil / más rápida?
Llamando al método usando dll import. Es rápido y fácil de usar :)
[DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr MemSet(IntPtr dest, int c, int byteCount);
c es el valor que desea establecer en la memoria
O
[DllImport("kernel32.dll", EntryPoint="RtlZeroMemory")]
public unsafe static extern bool ZeroMemory(byte* destination, int length);
esto solo establece la matriz dada a cero
Pruebe Array.Clear() :
Establece un rango de elementos en la matriz a cero, a
false
o anull
(Nothing en Visual Basic), dependiendo del tipo de elemento.
Varias personas han publicado respuestas y luego las han eliminado, diciendo que en cualquier idioma un bucle for será igual de efectivo que un memset o FillMemory o lo que sea.
Por ejemplo, un compilador puede dividirlo en fragmentos alineados de 64 bits para aprovechar una instrucción de asignación cero de 64 bits, si está disponible. Tomará alineación y cosas en consideración. La implementación de Memset ciertamente no es trivial.
un memset.asm . También vea memset-is-faster-than-simple-loop.html .
Nunca subestimes la infinita tortuosidad del compilador y los escritores de la biblioteca estándar.
ACTUALIZAR
Con base en el benchmark respecto al Array.Clear()
y array[x] = default(T)
, podemos afirmar que hay dos casos principales que se deben considerar al hacer la puesta a cero y la matriz:
A) Hay una matriz que tiene 1.76 elementos de longitud ;
B) Hay una matriz que tiene 77 elementos de longitud .
Entonces, la línea naranja en el diagrama representa el enfoque Array.Clear()
.
La línea azul en el diagrama representa el método array[x] = default(T)
(iteración sobre el conjunto y estableciendo sus valores por default(T)
).
Puedes escribir una vez un Ayudante para hacer este trabajo, así:
public static class ArrayHelper
{
// Performance-oriented algorithm selection
public static void SelfSetToDefaults<T>(this T[] sourceArray)
{
if (sourceArray.Length <= 76)
{
for (int i = 0; i < sourceArray.Length; i++)
{
sourceArray[i] = default(T);
}
}
else { // 77+
Array.Clear(
array: sourceArray,
index: 0,
length: sourceArray.Length);
}
}
}
Uso:
someArray.SelfSetToDefaults();
Array.Clear(integerArray, 0, integerArray.Length);
C ++:
memset(array, 0, array_length_in_bytes);
C ++ 11:
array.fill(0);
C #:
Array.Clear(array, startingIndex, length);
Java:
Arrays.fill(array, value);