c# - ParallelEnumerable.Aggregate for several methods -


start learn multithreading. have 3 methods calculate sum, average, , product of square roots of array.

at first, make 3 separate blocking calls using plinq. thought nice able make in single call , return object sum, product, , average @ same time. read parallelenumerable.aggregate can me this, totally don't know how use it.

i grateful explanation how use function in case, good/bad aspects of approach.

public static double average(double[] array, string tool)         {             if (array == null) throw new argumentnullexception(nameof(array));             double sum = enumerable.sum(array);             double result = sum / array.length;             print(tool, result);             return result;         }          public static double sum(double[] array, string tool)         {             if (array == null) throw new argumentnullexception(nameof(array));             double sum = enumerable.sum(array);             print(tool, sum);             return sum;         }          public static void productofsquareroots(double[] array, string tool)         {             if (array == null) throw new argumentnullexception(nameof(array));             double result = 1;             foreach (var number in array)             {                 result = result * math.sqrt(number);             }             print(tool, result);         } 

the 3 aggregated values (average, sum , product of square roots) want compute can each computed performing single pass on numbers. instead of doing 3 times (one each aggregated value) can once , aggregate 3 values inside loop (this should save time).

the average sum divided count , computing sum need count in addition average. if know size of input don't have count items here assume size of input unknown in advance.

if want use linq can use aggregate:

var aggregate = numbers.aggregate(     // starting value accumulator.     (count: 0, sum: 0d, productofsquareroots: 1d),     // update accumulator specific number.     (accumulator, number) =>     {         accumulator.count += 1;         accumulator.sum += number;         accumulator.productofsquareroots *= math.sqrt(number);         return accumulator;     }); 

the variable aggregate valuetuple<int, double, double> items count, sum , productofsquareroots. before c# 7 use anonymous type. however, require allocation each value in input sequence slowing down aggregation. using mutable value tuple aggregation should become faster.

aggregate works plinq if numbers of type parallelquery<t> , not ienumerable<t> aggregation performed in parallel. notice requires aggregation both associative (e.g. (a + b) + c = + (b + c) , commutative (e.g. a + b = b + a) in case true.

plinq has overhead might not perform better compared single threaded linq depending on number of elements in sequence , how complex calculations are. have measure determine if plinq speeds things up. however, can use same aggregate expression in both linq , plinq making code easy switch single threaded parallel inserting asparallel() right place.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -