c# - PLINQ (C#/.Net 4.5.1) 与 Stream (JDK/Java 8) 性能对比

标签 c# java performance java-8

我正在尝试比较 Java 8 和 PLINQ (C#/.Net 4.5.1) 中的并行流之间的性能。

这是我在我的机器上得到的结果(系统制造商 Dell Inc. 系统型号 Precision M4700 Processor Intel(R) Core(TM) i7-3740QM CPU @ 2.70GHz, 2701 Mhz, 4 Core(s), 8 Logical安装的处理器 物理内存 (RAM) 16.0 GB 操作系统名称 Microsoft Windows 7 Enterprise Version 6.1.7601 Service Pack 1 Build 7601)

C# .Net 4.5.1(X64 版本)

连续剧:

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

平均:490.6373

并行:

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

平均:180.5496

Java 8 (X64)

连续剧:

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

平均:326.241715

并行:

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

平均:70.3286

看起来 PLINQ 不能跨 CPU 内核扩展。我想知道我是否遗漏了什么。

这是 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)));
}
}

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)));
}

最佳答案

两个运行时都会决定使用多少线程来完成并行操作。这是一个非常重要的任务,可以考虑很多因素,包括任务受 CPU 限制的程度、完成任务的估计时间等。

每个运行时都是关于使用多少线程来解决请求的不同决定。就系统范围的调度而言,这两个决定显然是对还是错,但 Java 策略执行基准测试的效果更好(并且为系统上的其他任务留出更少的 CPU 资源)。

关于c# - PLINQ (C#/.Net 4.5.1) 与 Stream (JDK/Java 8) 性能对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23771022/

相关文章:

java - 对 CXF 服务器的 C/C++ SSL 请求

SQL:速度改进 - 在 cond1 或 cond2 上左连接

c# - Base-64 字符数组的长度无效

java - 如何在 Spring 测试中连接依赖关系

c# - 组合框不会加载数据库值

java - LibGDX - tile/tilemaps 中的纹理文本

c# - 在 64 位下执行缓慢。可能是 RyuJIT 错误?

c - Linux 共享内存同步

c# - 在控制台中填写最后一行

c# - 无法关闭/处置 SQLite 数据库 C# 上的文件锁