Why is my ASOdered PLINQ query faster than my unordered

I wrote some basic code examples to get familiar with PLINQ.

I stumbled upon something strange. I do not know if there was an error in my code or an error in my understanding of PLINQ.

The MSDN documentation states that adding AsOrdered () will preserve the order of the call at a possible cost of performance.

I wrote some unit tests and noticed the effect on the order in the result set as indicated in the documentation. But I saw the opposite effect on performance.

Here is my method:

public IEnumerable<int> ParallelCalculatePrimesUpTo(int maxValue)
{
    return from number in Enumerable.Range(1, maxValue).AsParallel()
            where IsPrime(number)
            select number;
}

public IEnumerable<int> OrderedParallelCalculatePrimesUpTo(int maxValue)
{
    return from number in Enumerable.Range(1, maxValue).AsParallel().AsOrdered()
            where IsPrime(number)
            select number;
}

And my very simple tests

    [TestMethod]
    public void SimplisticBenchmark6()
    {
        var primeNumberCalculator = new PrimeNumberCalculator();

        var startTime = DateTime.Now;

        primeNumberCalculator.ParallelCalculatePrimesUpTo(10000000).ToList();

        var totalTime = DateTime.Now - startTime;

        Console.WriteLine(totalTime);
    }

    [TestMethod]
    public void SimplisticBenchmark7()
    {
        var primeNumberCalculator = new PrimeNumberCalculator();

        var startTime = DateTime.Now;

        primeNumberCalculator.OrderedParallelCalculatePrimesUpTo(10000000).ToList();

        var totalTime = DateTime.Now - startTime;

        Console.WriteLine(totalTime);
    }

, , . 4 . 18 22 . ( ).

10 000 000 6 000 000, , , 3 000 000, .

, .

IsPrime, PLINQ:

// uses inneficient trial division algorithm
private bool IsPrime(int number)
{
    if (number == 1)
        return false;

    for (int divisor = 2; divisor <= Math.Sqrt(number); divisor++)
    {
        if (number % divisor == 0)
            return false;
    }

    return true;
}

?

+5
2

?

, , , , "" . :

static void Main(string[] args)
{
    const int size = 9000000;
    BenchIt("Parallel", ParallelCalculatePrimesUpTo, size);
    BenchIt("Ordered ", OrderedParallelCalculatePrimesUpTo, size);
    Console.ReadKey();
}

public static void BenchIt(string desc, Func<int, IEnumerable<int>> myFunc, int size)
{
    var sw = new Stopwatch();            
    sw.Restart();
    myFunc.Invoke(size).ToList();
    sw.Stop();
    Console.WriteLine("{0} {1}",desc, sw.Elapsed);
}

, , . . , , , . , , . , - , .

- . .

?

PLINQ , . , ; IsPrime .

ParallelCalculatedPrimesUpTo verse OrderedParallelCalculatePrimesUpTo? ; , , , . - , - , , - . ( , ).

+3

, 4 ? , AsOrdered() . , .

, .NET Framework (int.Range) AsOrdered(). , , .

(, , ). , ?

+1

All Articles