¿Existe una forma mejor y más corta que iterar sobre la matriz?
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
aclaración:
Un código primario mejor significa un código más limpio, pero también se agradecen las sugerencias sobre la mejora del rendimiento. (Como ya se mencionó: dividir matrices grandes).
No es como si estuviera buscando una mejora espectacular en el rendimiento, solo me preguntaba si este tipo de azúcar sintáctico no estaba ya disponible: "Hay String.Join - ¿qué diablos pasa con int []?".
Respuestas:
Siempre que pueda usar .NET 3.5 (o más reciente) y LINQ, intente
fuente
System.OverflowException
si el resultado fuera mayor de lo que puede caber en un entero de 32 bits con signo (es decir, (2 ^ 31) -1 o en inglés ~ 2.1 mil millones).int sum = arr.AsParallel().Sum();
una versión más rápida que usa múltiples núcleos de la CPU. Para evitarSystem.OverflowException
, puede usarlong sum = arr.AsParallel().Sum(x => (long)x);
Para versiones aún más rápidas que evitan la excepción de desbordamiento y admiten todos los tipos de datos enteros y usan instrucciones SIMD / SSE paralelas de datos, eche un vistazo al paquete HPCsharp nugetSí hay. Con .NET 3.5:
Si no está utilizando .NET 3.5, puede hacer esto:
fuente
foreach
bucle está disponible en todas las versiones de C #.foreach
simplemente sustituye una línea de código por otra y no es más corta. Aparte de eso, aforeach
está perfectamente bien y es más legible.foreach (int i in arr) sum += i;
Con LINQ:
fuente
Depende de cómo se defina mejor. Si desea que el código se vea más limpio, puede usar .Sum () como se menciona en otras respuestas. Si desea que la operación se ejecute rápidamente y tiene una matriz grande, puede hacerla paralela dividiéndola en sumas secundarias y luego sumando los resultados.
fuente
Una alternativa también es utilizar el
Aggregate()
método de extensión.fuente
Si no prefiere LINQ, es mejor usar foreach loop para evitar el índice.
fuente
Para arreglos extremadamente grandes, puede resultar útil realizar el cálculo utilizando más de un procesador / núcleo de la máquina.
fuente
Un problema con las soluciones de bucle for anteriores es que para la siguiente matriz de entrada con todos los valores positivos, el resultado de la suma es negativo:
La suma es -2147483648, ya que el resultado positivo es demasiado grande para el tipo de datos int y se desborda en un valor negativo.
Para la misma matriz de entrada, las sugerencias arr.Sum () provocan que se lance una excepción de desbordamiento.
Una solución más sólida es utilizar un tipo de datos más grande, como un "largo" en este caso, para la "suma" de la siguiente manera:
La misma mejora funciona para la suma de otros tipos de datos enteros, como short y sbyte. Para matrices de tipos de datos enteros sin signo como uint, ushort y byte, el uso de unsigned long (ulong) para la suma evita la excepción de desbordamiento.
La solución de bucle for también es muchas veces más rápida que Linq .Sum ()
Para ejecutarse aún más rápido, el paquete HPCsharp nuget implementa todas estas versiones .Sum (), así como las versiones SIMD / SSE y las paralelas multinúcleo, para un rendimiento mucho más rápido.
fuente
long sum = arr.Sum(x => (long)x);
cuál funciona bien en C # usando Linq. Proporciona la máxima precisión para la suma de todos los tipos de datos enteros con signo: sbyte, short e int. También evita lanzar una excepción de desbordamiento y es muy compacto. No tiene un rendimiento tan alto como el bucle for anterior, pero el rendimiento no es necesario en todos los casos.El uso de foreach sería un código más corto, pero probablemente realice exactamente los mismos pasos en tiempo de ejecución después de que la optimización JIT reconozca la comparación con la longitud en la expresión de control del bucle for.
fuente
En una de mis aplicaciones usé:
fuente
.Aggregate()
método de extensión.Una mejora en la buena implementación de Parallel.ForEach multinúcleo de Theodor Zoulias:
que funciona para tipos de datos enteros sin signo, ya que C # solo admite Interlocked.Add () para int y long. La implementación anterior también se puede modificar fácilmente para admitir otros tipos de datos enteros y de punto flotante para realizar la suma en paralelo utilizando múltiples núcleos de la CPU. Se utiliza en el paquete nuget de HPCsharp.
fuente
Prueba este código:
El resultado es:
fuente