Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does AsParallel() split it's 'source'?

I'm trying to determine how AsParallel() splits it's 'source', and indeed what is meant by 'source'...

For example...

public class CSVItem
{
    public DateTime Date { get; set; }
    public string AccountNumber { get; set; }
}

List<CSVItem> CSVItemList = new List<CSVItem>();

Then put 500k varying CSVItem's into CSVItemList.

Then use:

CSVItemList = CSVItemList.AsParallel().OrderBy(x => x.AccountNumber).ThenBy(q => q.Date).ToList();

Will it only split the 'source' (meaning for example 250k records onto each of two threads) onto multiple asynch threads and perform the OrderBy().ThenBy() on each thread then merge the results...

Or will it separate the OrderBy() and ThenBy() onto separate threads and run them and then merge the results... giving a strangely ordered list?

like image 792
Paul Zahra Avatar asked Jul 10 '15 12:07

Paul Zahra


2 Answers

It gose one by one a) done with OrderBy merge result and than gose for b) ThenBy. Below image form Albahari blog shows how it works i.e. it take one by one

enter image description here

Q: how many number of task

A : you can decide this by using WithDegreeOfParallelism forces PLINQ to run the specified number of tasks simultaneously

   //create 5 task
   List.AsParallel().WithDegreeOfParallelism(5)

Check this : Parallel Programming

like image 163
Pranay Rana Avatar answered Nov 11 '22 10:11

Pranay Rana


I created a little example to check, which one is true.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    static void Main(string[] args)
    {
        List<TestItem> items = new List<TestItem>();
        List<TestItem> itemsNonParallel = new List<TestItem>();

        items.Add(new TestItem() { Age = 1, Size = 12 });
        items.Add(new TestItem() { Age = 2, Size = 1 });
        items.Add(new TestItem() { Age = 5, Size = 155 });
        items.Add(new TestItem() { Age = 23, Size = 42 });
        items.Add(new TestItem() { Age = 7, Size = 32 });
        items.Add(new TestItem() { Age = 9, Size = 22 });
        items.Add(new TestItem() { Age = 34, Size = 11 });
        items.Add(new TestItem() { Age = 56, Size = 142 });
        items.Add(new TestItem() { Age = 300, Size = 13 });

        itemsNonParallel.Add(new TestItem() { Age = 1, Size = 12 });
        itemsNonParallel.Add(new TestItem() { Age = 2, Size = 1 });
        itemsNonParallel.Add(new TestItem() { Age = 5, Size = 155 });
        itemsNonParallel.Add(new TestItem() { Age = 23, Size = 42 });
        itemsNonParallel.Add(new TestItem() { Age = 7, Size = 32 });
        itemsNonParallel.Add(new TestItem() { Age = 9, Size = 22 });
        itemsNonParallel.Add(new TestItem() { Age = 34, Size = 11 });
        itemsNonParallel.Add(new TestItem() { Age = 56, Size = 142 });
        itemsNonParallel.Add(new TestItem() { Age = 300, Size = 13 });

        foreach (var item in items.AsParallel().OrderBy(x => x.Age).ThenBy(x => x.Size))
        {
            Console.WriteLine($"Age: {item.Age}     Size: {item.Size}");
        }

        Console.WriteLine("---------------------------");

        foreach (var item in itemsNonParallel.OrderBy(x => x.Age).ThenBy(x => x.Size))
        {
            Console.WriteLine($"Age: {item.Age}     Size: {item.Size}");
        }

        Console.ReadLine();        
    }
}

public class TestItem
{
    public int Age { get; set; }
    public int Size { get; set; }
}

Result

AsParallel() does what we want. It first processes the OrderBy() parallel, merges back the list and then moves on to the next query, in our case ThenBy().

like image 31
greenhoorn Avatar answered Nov 11 '22 09:11

greenhoorn