using System; using System.Collections.Concurrent; using System.Diagnostics.Contracts; using System.Linq; using System.Threading.Tasks; namespace BenchApp { class Program { static void Main(string[] args) { double[] a = new double[16 * 1024 * 1024]; Random rnd = new Random(0); for (int i = 0; i < a.Length; i++) { a[i] = rnd.NextDouble() * rnd.Next(1000); } var etalonSum = Enumerable.Sum(a); var anothersum = a.Sum(); Console.WriteLine(etalonSum); Console.WriteLine(anothersum); } } public static class Test { [Pure] public static double Sum(this double[] source) { if (source.Length < Constants.SingleThreadExecutionThreshold) return Sum(source, 0, source.Length); double result = 0; object syncRoot = new object(); Parallel.ForEach(Partitioner.Create(0, source.Length), () => (double)0, (range, state, sum) => Sum(source, range.Item1, range.Item2), x => { lock (syncRoot) result += x; }); return result; } [Pure] private static double Sum(this double[] source, int startIndex, int endIndex) { double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; checked { int i; for (i = startIndex; i < endIndex - Constants.Step + 1; i += Constants.Step) { sum1 += source[i]; sum2 += source[i + 1]; sum3 += source[i + 2]; sum4 += source[i + 3]; } if (i == source.Length) return ((sum1 + sum2) + (sum3 + sum4)); if (i == source.Length - 1) return ((sum1 + sum2) + (sum3 + sum4) + source[i]); if (i == source.Length - 2) return ((sum1 + sum2) + (sum3 + sum4) + (source[i] + source[i + 1])); return ((sum1 + sum2) + (sum3 + sum4) + (source[i] + source[i + 1] + source[i + 2])); } } internal static class Constants { public const int Step = 4; public const int SingleThreadExecutionThreshold = 1024; } } }