【问题标题】:Pass in lists in the Parallel.ForEach在 Parallel.ForEach 中传入列表
【发布时间】:2019-02-18 03:19:11
【问题描述】:

这是我第一次尝试使用“Parallel.ForEach”循环来查看是否可以使用系统中的多个内核来提高性能。我曾尝试查看 MSDN 和其他示例,但找不到传递以下 3 个列表的方法。

如何将此循环与 Parallel.ForEach 循环交换? 我想我正在寻找如何传递所有这 3 个列表的基础知识,以便我可以在 Parallel.ForEach 循环中使用它们?

谢谢!

        List<double> nums = new List<double> { 0.0005, 0.00035, 0.00205 };
        List<double> list1 = new List<double>();
        List<double> list2 = new List<double>();
        List<double> list3 = new List<double>(); Random random = new Random(); double calc1 = 0;
        List<double> resultLIST = new List<double>();
        for (int i = 0; i < 4000000; i++)
        {
            list1.Add(nums[random.Next(0, 7)]);
            list2.Add(nums[random.Next(0, 7)]);
            list3.Add(nums[random.Next(0, 7)]);
        }

        //How can the below loop be replaced with a: Parallel.ForEach loop?
        for (int i = 0; i < list1.Count; i++)
        {
            calc1 = list1[i] * list2[i] * list3[i];
            resultLIST.Add(calc1);
        }

        //Now sort the list 
        resultLIST.Sort();

        //Here I will write "resultLIST" to a .txt file

【问题讨论】:

  • 不清楚你在问什么。我们不知道list2 或`list3` 代表什么,或者你打算用它们做什么。如果您只想将一个列表标记到前一个列表的末尾,那么您可以使用list1.Concat(list2).Concat(list3)
  • 这听起来像是XY-problem。您真正想要完成什么?
  • 附带说明,您的第一行可以替换为List&lt;double&gt; nums = new List&lt;double&gt; { 0.0005, 0.00035, 0.00205 };
  • 这是非常低质量的,请解释你想用这个做什么,为什么。就目前而言,这里没有问题,只是一个思想泡泡
  • 如果我的问题令人困惑,我很抱歉。这是我第一次使用这个 Parallel.ForEach 循环,所以我不确定在放置代码时是否遗漏了什么。如果这样更清楚,我已经更改了问题?

标签: c# multicore parallel.foreach


【解决方案1】:

就个人而言,我会将 LINQ 与 AsParallel 一起使用:

var result = Enumerable.Range(0, list1.Count)
    .AsParallel()
    .Select(index => list1[index] + list2[index] + list3[index])
    .OrderBy(v => v)
    .ToList();

请注意,list1list2list3 在此计算期间预计不会发生变化。

【讨论】:

  • 这对我来说看起来很新,我不确定我是否能了解那里发生的事情。这与 Parallel.ForEach 循环相同吗?我相信我必须调查一下。为什么在使用 Parallel.ForEach 循环之前更喜欢这种方法。这是一种更快的方法吗?该方法是否利用了系统中的内核数量,例如 24 个内核?
  • 我更喜欢它,因为这意味着我不必手动同步结果列表,或使用ConcurrentBag 等。您可以阅读AsParallel here 的文档。
  • 我什至会选择更简单的Enumerable.Range(0, 4000000).AsParallel().Select(i =&gt; list1[i] * list2[i] * list3[i]).ToList()
  • 现在,作为一个旁注:使用.OrderBy(v =&gt; v),然后使用.AsParallel(),但没有.OrderBy(v =&gt; v),在没有.AsParallel() 的情况下执行此操作会更快。
  • 感谢所有 cmets。我想我需要阅读有关 AsParallel 的文档,以便了解更多基础知识。研究这些方法非常有趣。
【解决方案2】:

当每个列表上的操作可以并行独立运行时,您可以使用 Parallel.Foreach。在你的情况下,你不能。还要记住,将 Parallel.Foreach 或 AsParallel 用于 * 或 + 之类的琐碎操作实际上会降低性能,因为开销更大。

在您的情况下,最好的方法是拆分所有三个列表,每个列表包含 1000000 个元素。将它们添加到数组数组中并在它们上调用 Parallel.Foreach。这样,您将拥有 4 个线程,每个线程执行 1000000 次操作,如果您的机器有 4 个内核,它们可以在每个内核上独立运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    相关资源
    最近更新 更多