Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel Aggregate Collection

I have seen code for parallel aggregation for basic types, e.g.

Parallel.For<int>(0, result.Count, () => 0, (i, loop, subtotal) =>
    {
        subtotal += result[i];
        return subtotal;
    },
    (x) => Interlocked.Add(ref sum, x)
);

I was wondering if there was an equivalent for a list/other collection e.g:

List<Result> AllResults;
Parallel.ForEach(allIDs, (currentID) =>
{

    subList.add(GetResultFor(currentID));
    return subList;
},
(x) =>
{
    lock(AllResults)
        AllResults.AddRange(subList);
};

I am guessing there is nothing that nice and neat but I can't think of another way of doing it, certainly not through a standard parralel.ForEach because I cant think of how you would say "this core have this range, this core this range"....

like image 636
chrispepper1989 Avatar asked May 02 '26 13:05

chrispepper1989


1 Answers

I think in both examples, PLINQ can serve you better and without any need to manually lock while using non thread-safe collections.

Your sum calculation can be converted to:

var sum = result.AsParallel().Sum();

And you second example with the List<T> can be converted to:

List<Result> results = allIDs.AsParallel()
                             .Select(id => GetResultFor(id))
                             .ToList();

Note parallelism is only as good as what tests say. Not always will going parallel speed up your code, there are times where it may even degrade performance against a sequential loop.

like image 115
Yuval Itzchakov Avatar answered May 04 '26 02:05

Yuval Itzchakov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!