Existe uma maneira mais curta melhor do que iterar no array?
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
esclarecimento:
Melhor primário significa código mais limpo, mas dicas sobre melhoria de desempenho também são bem-vindas. (Como já mencionado: dividindo grandes arrays).
Não é como se eu estivesse procurando por uma melhoria de desempenho matadora - eu apenas me perguntei se esse tipo de açúcar sintático já não estava disponível: "Há String.Join - que diabos sobre int []?".
Respostas:
Desde que você possa usar .NET 3.5 (ou mais recente) e LINQ, tente
fonte
System.OverflowException
se o resultado for maior do que você pode caber em um inteiro de 32 bits com sinal (ou seja, (2 ^ 31) -1 ou em inglês ~ 2,1 bilhões).int sum = arr.AsParallel().Sum();
uma versão mais rápida que usa vários núcleos da CPU. Para evitar,System.OverflowException
você pode usarlong sum = arr.AsParallel().Sum(x => (long)x);
Para versões ainda mais rápidas que evitam exceção de estouro e suportam todos os tipos de dados inteiros e usam instruções SIMD / SSE paralelas de dados, dê uma olhada no pacote HPCsharp nugetSim existe. Com .NET 3.5:
Se você não estiver usando .NET 3.5, poderá fazer o seguinte:
fonte
foreach
loop está disponível em todas as versões do C #.foreach
apenas substitui uma linha de código por outra e não é mais curta. Além disso, aforeach
está perfeitamente correto e é mais legível.foreach (int i in arr) sum += i;
Com LINQ:
fonte
Depende de como você define melhor. Se quiser que o código tenha uma aparência mais limpa, você pode usar .Sum () conforme mencionado em outras respostas. Se quiser que a operação seja executada rapidamente e tiver uma grande matriz, você pode torná-la paralela dividindo-a em sub-somas e, em seguida, somar os resultados.
fonte
Uma alternativa também é usar o
Aggregate()
método de extensão.fonte
Se você não preferir o LINQ, é melhor usar o loop foreach para evitar fora do índice.
fonte
Para matrizes extremamente grandes, pode valer a pena realizar o cálculo usando mais de um processador / núcleos da máquina.
fonte
Um problema com as soluções de loop for acima é que para a seguinte matriz de entrada com todos os valores positivos, o resultado da soma é negativo:
A soma é -2147483648, pois o resultado positivo é muito grande para o tipo de dados int e transborda para um valor negativo.
Para a mesma matriz de entrada, as sugestões arr.Sum () fazem com que uma exceção de estouro seja lançada.
Uma solução mais robusta é usar um tipo de dados maior, como um "longo" neste caso, para a "soma" da seguinte maneira:
A mesma melhoria funciona para a soma de outros tipos de dados inteiros, como short e sbyte. Para matrizes de tipos de dados inteiros sem sinal, como uint, ushort e byte, o uso de um longo sem sinal (ulong) para a soma evita a exceção de estouro.
A solução do loop for também é muitas vezes mais rápida que Linq .Sum ()
Para funcionar ainda mais rápido, o pacote HPCsharp nuget implementa todas essas versões .Sum (), bem como versões SIMD / SSE e paralelas com vários núcleos, para desempenho muitas vezes mais rápido.
fonte
long sum = arr.Sum(x => (long)x);
que funciona bem em C # usando Linq. Ele fornece a precisão total para a soma de todos os tipos de dados inteiros com sinal: sbyte, short e int. Ele também evita o lançamento de uma exceção de estouro e é bem compacto. Não é um desempenho tão alto quanto o loop for acima, mas o desempenho não é necessário em todos os casos.Usar foreach seria um código mais curto, mas provavelmente executaria exatamente as mesmas etapas em tempo de execução depois que a otimização JIT reconhecer a comparação com Length na expressão de controle do loop for.
fonte
Em um de meus aplicativos eu usei:
fonte
.Aggregate()
método de extensão.Uma melhoria na boa implementação Parallel.ForEach multi-core de Theodor Zoulias:
que funciona para tipos de dados inteiros sem sinal, uma vez que C # suporta apenas Interlocked.Add () para int e long. A implementação acima também pode ser facilmente modificada para oferecer suporte a outros tipos de dados inteiros e de ponto flutuante para fazer a soma em paralelo usando vários núcleos da CPU. É usado no pacote nuget HPCsharp.
fonte
Experimente este código:
O resultado é:
fonte