c# - 如何确定并行 foreach 循环的性能是否优于 foreach 循环?

标签 c# .net asynchronous foreach parallel-processing

我刚刚在 .NET Fiddle 中做了一个简单的测试,对 100 个长度为 1000 的随机整数数组进行排序,看看使用 Paralell.ForEach 循环这样做是否比普通的旧 foreach 更快 循环。

这是我的代码(我很快就把它放在一起了,所以请忽略代码的重复和整体糟糕的外观)

using System;
using System.Net;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;

public class Program
{
    public static int[] RandomArray(int minval, int maxval, int arrsize)
    {
        Random randNum = new Random();
        int[] rand = Enumerable
            .Repeat(0, arrsize)
            .Select(i => randNum.Next(minval, maxval))
            .ToArray(); 
        return rand;
    }

    public static void SortOneThousandArraysSync()
    {
        var arrs = new List<int[]>(100);
        for(int i = 0; i < 100; ++i)
            arrs.Add(RandomArray(Int32.MinValue,Int32.MaxValue,1000));
        Parallel.ForEach(arrs, (arr) =>
        {
            Array.Sort(arr);
        });
    }

    public static void SortOneThousandArraysAsync()
    {
        var arrs = new List<int[]>(100);
        for(int i = 0; i < 100; ++i)
            arrs.Add(RandomArray(Int32.MinValue,Int32.MaxValue,1000));
        foreach(var arr in arrs)
        {
            Array.Sort(arr);
        };      
    }

    public static void Main()
    {
        var start = DateTime.Now;
        SortOneThousandArraysSync();
        var end = DateTime.Now;
        Console.WriteLine("t1 = " + (end - start).ToString());
        start = DateTime.Now;
        SortOneThousandArraysAsync();
        end = DateTime.Now;
        Console.WriteLine("t2 = " + (end - start).ToString());
    }
}

这是点击运行两次后的结果:

t1 = 00:00:00.0156244
t2 = 00:00:00.0156243

...

t1 = 00:00:00.0467854
t2 = 00:00:00.0156246

...

因此,有时速度更快,有时则差不多。

可能的解释:

  • 在我运行的第二次测试中,同步数组与异步数组相比,随机数组“更未排序”
  • 它与在 .NET Fiddle 上运行的进程有关。在第一种情况下,并行操作基本上像非并行操作一样运行,因为我的 fiddle 没有任何线程可以接管。 (或类似的东西)

想法?

最佳答案

如果循环中的代码需要大量时间来执行,您应该只使用 Parallel.ForEach()。在这种情况下,创建多个线程,对数组进行排序,然后将结果组合到一个线程上比在单个线程上简单地排序要花费更多的时间。例如,以下代码片段中的 Parallel.ForEach() 比普通的 ForEach 循环执行时间更短:

public static void Main(string[] args)
{
    var numbers = Enumerable.Range(1, 10000);

    Parallel.ForEach(numbers, n => Factorial(n));

    foreach (var number in numbers)
    {
        Factorial(number);
    }
}

private static int Factorial(int number)
{
    if (number == 1 || number == 0)
        return 1;

    return number * Factorial(number - 1);
}

但是,如果我将 var numbers = Enumerable.Range(1, 10000); 更改为 var numbers = Enumerable.Range(1, 1000);,ForEach循环比 Parallel.ForEach() 更快。​​

关于c# - 如何确定并行 foreach 循环的性能是否优于 foreach 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40443350/

相关文章:

.net - 在第三方 .NET 程序集上更改平台目标

c# - 以编程方式创建照片马赛克

asynchronous - Tornado,使用同步代码的参数运行协程方法

c# - 将文件从 MemoryStream 附加到 C# 中的 MailMessage

c# - 在 ASP.NET 中查找使用特定接口(interface)的控件

c# - object.ReferenceEquals 或 == 运算符?

.net - TPL 数据流与普通信号量

c# - 如何在 RestSharp 中使用 ExecuteAsync 返回变量

c# - 调用 Task.Delay() 并在几分钟后询问还剩多少时间

c# - 在 Tensorflow.NET 中加载模型的最佳方式是什么