Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PLINQ (C#/.Net 4.5.1) vs Stream (JDK/Java 8) Performance

I am trying to compare performance between parallel streams in Java 8 and PLINQ (C#/.Net 4.5.1).

Here is the result I get on my machine ( System Manufacturer Dell Inc. System Model Precision M4700 Processor Intel(R) Core(TM) i7-3740QM CPU @ 2.70GHz, 2701 Mhz, 4 Core(s), 8 Logical Processor(s) Installed Physical Memory (RAM) 16.0 GB OS Name Microsoft Windows 7 Enterprise Version 6.1.7601 Service Pack 1 Build 7601)

C# .Net 4.5.1 (X64-release)

Serial:

470.7784, 491.4226, 502.4643, 481.7507, 464.1156, 463.0088, 546.149, 481.2942, 502.414, 483.1166

Average: 490.6373

Parallel:

158.6935, 133.4113, 217.4304, 182.3404, 184.188, 128.5767, 160.352, 277.2829, 127.6818, 213.6832

Average: 180.5496

Java 8 (X64)

Serial:

471.911822, 333.843924, 324.914299, 325.215631, 325.208402, 324.872828, 324.888046, 325.53066, 325.765791, 325.935861

Average:326.241715

Parallel:

212.09323, 73.969783, 68.015431, 66.246628, 66.15912, 66.185373, 80.120837, 75.813539, 70.085948, 66.360769

Average:70.3286

It looks like PLINQ does not scale across the CPU cores. I am wondering if I miss something.

Here is the code for C#:

class Program
{
    static void Main(string[] args)
    {
        var NUMBER_OF_RUNS = 10;
        var size = 10000000;
        var vals = new double[size];

    var rnd = new Random();
    for (int i = 0; i < size; i++)
    {
        vals[i] = rnd.NextDouble();
    }

    var avg = 0.0;
    Console.WriteLine("Serial:");
    for (int i = 0; i < NUMBER_OF_RUNS; i++)
    {
        var watch = Stopwatch.StartNew();
        var res = vals.Select(v => Math.Sin(v)).ToArray();
        var elapsed = watch.Elapsed.TotalMilliseconds;
        Console.Write(elapsed + ", ");

        if (i > 0)
            avg += elapsed;
    }
    Console.Write("\nAverage: " + (avg / (NUMBER_OF_RUNS - 1)));

    avg = 0.0;
    Console.WriteLine("\n\nParallel:");
    for (int i = 0; i < NUMBER_OF_RUNS; i++)
    {
        var watch = Stopwatch.StartNew();
        var res = vals.AsParallel().Select(v => Math.Sin(v)).ToArray();
        var elapsed = watch.Elapsed.TotalMilliseconds;
        Console.Write(elapsed + ", ");

        if (i > 0)
            avg += elapsed;
    }
    Console.Write("\nAverage: " + (avg / (NUMBER_OF_RUNS - 1)));
}
}

Here is the code for Java:

import java.util.Arrays;
import java.util.Random;
import java.util.stream.DoubleStream;

public class Main {
    private static final Random rand = new Random();
    private static final int MIN = 1;
    private static final int MAX = 140;
    private static final int POPULATION_SIZE = 10_000_000;
    public static final int NUMBER_OF_RUNS = 10;
public static void main(String[] args) throws InterruptedException {
    Random rnd = new Random();
    double[] vals1 = DoubleStream.generate(rnd::nextDouble).limit(POPULATION_SIZE).toArray();

    double avg = 0.0;
    System.out.println("Serial:");
    for (int i = 0; i < NUMBER_OF_RUNS; i++)
    {
        long start = System.nanoTime();
        double[] res = Arrays.stream(vals1).map(Math::sin).toArray();
        double duration = (System.nanoTime() - start) / 1_000_000.0;
        System.out.print(duration + ", " );

        if (i > 0)
            avg += duration;
    }
    System.out.println("\nAverage:" + (avg / (NUMBER_OF_RUNS - 1)));

    avg = 0.0;
    System.out.println("\n\nParallel:");
    for (int i = 0; i < NUMBER_OF_RUNS; i++)
    {
        long start = System.nanoTime();
        double[] res = Arrays.stream(vals1).parallel().map(Math::sin).toArray();
        double duration = (System.nanoTime() - start) / 1_000_000.0;
        System.out.print(duration + ", " );

        if (i > 0)
            avg += duration;            
    }
    System.out.println("\nAverage:" + (avg / (NUMBER_OF_RUNS - 1)));
}

}

like image 451
Bijan Avatar asked May 20 '14 22:05

Bijan


People also ask

What is parallel query in C#?

Net. Parallel LINQ, or PLINQ, is a query execution engine that runs on top of the managed environment of . Net and takes advantage of the multiple processors or cores in your computer system to execute the queries in parallel.

What is Linq in C# with example?

Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language. Traditionally, queries against data are expressed as simple strings without type checking at compile time or IntelliSense support.

Which extension method do you need to run a parallel query in PLINQ?

PLINQ. Assume, we want to execute the same query but in parallel. We can use AsParallel() method which is part of ParallelEnumerable class.


1 Answers

Both runtimes make a decision about how many threads to use in order to complete the parallel operation. That is a non-trivial task that can take many factors into account, including the degree to which the task is CPU bound, the estimated time to complete the task, etc.

Each runtime is different decisions about how many threads to use to resolve the request. Neither decision is obviously right or wrong in terms of system-wide scheduling, but the Java strategy performs the benchmark better (and leaves fewer CPU resources available for other tasks on the system).

like image 192
Eric J. Avatar answered Sep 20 '22 15:09

Eric J.