Existe-t-il un meilleur moyen plus court que d'itérer sur le tableau?
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
clarification:
Un meilleur primaire signifie un code plus propre, mais des conseils sur l'amélioration des performances sont également les bienvenus. (Comme déjà mentionné: division de grands tableaux).
Ce n'est pas comme si je cherchais une amélioration des performances de tueur - je me demandais juste si ce type de sucre syntaxique n'était pas déjà disponible: "Il y a String.Join - qu'est-ce que diable à propos de int []?".
Réponses:
À condition que vous puissiez utiliser .NET 3.5 (ou plus récent) et LINQ, essayez
la source
System.OverflowException
si le résultat est supérieur à ce que vous pouvez insérer dans un entier 32 bits signé (c'est-à-dire (2 ^ 31) -1 ou en anglais ~ 2,1 milliards).int sum = arr.AsParallel().Sum();
une version plus rapide qui utilise plusieurs cœurs du processeur. Pour éviter queSystem.OverflowException
vous puissiez utiliserlong sum = arr.AsParallel().Sum(x => (long)x);
Pour des versions encore plus rapides qui évitent les exceptions de débordement et prennent en charge tous les types de données entiers et utilisent des instructions SIMD / SSE parallèles aux données, jetez un œil au package HPCsharp nugetOui il y a. Avec .NET 3.5:
Si vous n'utilisez pas .NET 3.5, vous pouvez le faire:
la source
foreach
boucle est disponible dans toutes les versions de C #.foreach
remplace simplement une ligne de code par une autre et n'est pas plus courte. En dehors de cela, unforeach
est parfaitement bien et est plus lisible.foreach (int i in arr) sum += i;
Avec LINQ:
la source
Cela dépend de la façon dont vous définissez mieux. Si vous voulez que le code paraisse plus propre, vous pouvez utiliser .Sum () comme mentionné dans d'autres réponses. Si vous voulez que l'opération s'exécute rapidement et que vous avez un grand tableau, vous pouvez le rendre parallèle en le divisant en sous-sommes, puis en additionnant les résultats.
la source
Une alternative aussi d'utiliser la
Aggregate()
méthode d'extension.la source
Si vous ne préférez pas LINQ, il est préférable d'utiliser la boucle foreach pour éviter la sortie d'index.
la source
Pour les tableaux extrêmement volumineux, il peut être utile d'effectuer le calcul en utilisant plusieurs processeurs / cœurs de la machine.
la source
Un problème avec les solutions de boucle for ci-dessus est que pour le tableau d'entrée suivant avec toutes les valeurs positives, le résultat de la somme est négatif:
La somme est -2147483648, car le résultat positif est trop grand pour le type de données int et déborde en une valeur négative.
Pour le même tableau d'entrée, les suggestions arr.Sum () provoquent la levée d'une exception de débordement.
Une solution plus robuste consiste à utiliser un type de données plus grand, tel qu'un "long" dans ce cas, pour la "somme" comme suit:
La même amélioration fonctionne pour la sommation d'autres types de données entiers, tels que short et sbyte. Pour les tableaux de types de données entiers non signés tels que uint, ushort et byte, l'utilisation d'un unsigned long (ulong) pour la somme évite l'exception de dépassement de capacité.
La solution de la boucle for est également plusieurs fois plus rapide que Linq .Sum ()
Pour fonctionner encore plus vite, le package HPCsharp nuget implémente toutes ces versions .Sum () ainsi que les versions SIMD / SSE et les versions parallèles multicœurs, pour des performances beaucoup plus rapides.
la source
long sum = arr.Sum(x => (long)x);
ce qui fonctionne bien en C # en utilisant Linq. Il fournit la précision totale de la sommation pour tous les types de données entiers signés: sbyte, short et int. Cela évite également de lancer une exception de débordement et est bien compact. Ce n'est pas aussi performant que la boucle for ci-dessus, mais les performances ne sont pas nécessaires dans tous les cas.L'utilisation de foreach serait un code plus court, mais effectuez probablement exactement les mêmes étapes au moment de l'exécution après que l'optimisation JIT ait reconnu la comparaison à Length dans l'expression de contrôle de la boucle for.
la source
Dans l'une de mes applications, j'ai utilisé:
la source
.Aggregate()
méthode d'extension.Une amélioration de l'implémentation multi-core Parallel de Theodor Zoulias.
qui fonctionne pour les types de données entiers non signés, puisque C # ne prend en charge que Interlocked.Add () pour int et long. L'implémentation ci-dessus peut également être facilement modifiée pour prendre en charge d'autres types de données entiers et flottants pour effectuer une sommation en parallèle à l'aide de plusieurs cœurs du processeur. Il est utilisé dans le package HPCsharp nuget.
la source
Essayez ce code:
Le résultat est:
la source