Skip to content

ParallelEnumerable.ToDictionary does not parallelize #96262

Closed as not planned
Closed as not planned
@madelson

Description

@madelson

Description

I would expect the following to be a valid pattern, but it does not lead to parallel execution of ComputeExpensiveThing():

var resultsByItem = items.AsParallel().ToDictionary(i => i, i => ComputeExpensiveThing());

Reproduction Steps

    var items = Enumerable.Range(0, 100).AsParallel();
    var stopwatch = Stopwatch.StartNew();
    
    // completes in ~10s because there is no parallelism
    var dictionary = items.ToDictionary(i => i, i => { Thread.Sleep(100); return i; });
    
    // workaround completes in ~1s
    /*var dictionary = items.Select(i =>
        {
            Thread.Sleep(100);
            return new KeyValuePair<int, int>(i, i);
        })
        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);*/

    Console.WriteLine(stopwatch.Elapsed);

Expected behavior

From a parallelism perspective, I would expect

items.AsParallel().ToDictionary(i => ..., i => ...)

to be equivalent to:

items.AsParallel().Select(i => KeyValuePair.Create(..., ...)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

For example, ParallelEnumerable.Min() parallelizes its selector:

Enumerable.Range(1, 10).AsParallel().Min(i => { Thread.Sleep(1000); return i; }); // completes in ~1s

Actual behavior

keySelector and elementSelector execute serially

Regression?

No response

Known Workarounds

As shown above, pushing any non-trivial selectors up one layer into a Select call gets around the issue.

Configuration

.NET 8 Windows 11 x64

Other information

ParallelEnumerable.ToDictionary has a serial loop in which the selectors are executed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Linq.Parallelhelp wanted[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions