【问题标题】:Parallel.Foreach is not much faster than foreachParallel.Foreach 并不比 foreach 快多少
【发布时间】:2018-12-14 10:43:37
【问题描述】:

我有如下所示的 IEnumerable 集合。这是收藏的集合。 主集合有 10 个项目,每个项目有 100k 个项目。

我的 CPU 有 6 个内核,24GB RAM,1.5TB 硬盘。 3 个用户执行远程桌面。

 IEnumerable<AFValues> afValues = listAvgResults.Select(pointResults => pointResults[type]);

当我使用 Parallel.ForEach 时需要 9.8 秒,而 foreach 需要 10 秒。

MTObservableCollection<VesselData> vesselList = new MTObservableCollection<VesselData>();

Parallel.ForEach(afValues, pointValues =>
                        {
 vesselList.Add(row);
});

谢谢

【问题讨论】:

  • 你为什么希望一个简单的添加被加速?另外,你的锁呢?
  • 首先确定您的瓶颈在哪里以及它是否受 CPU 限制或 I/O 限制。 Parallel.ForEach 可以加速受 CPU 限制的工作,但前提是它适合并行化活动(例如,如果您需要锁定实际的 CPU 消耗活动,这将无济于事)。先配置文件,然后尝试优化。
  • 如果它不安全,它是否快速无关紧要。 ObservableCollection 不是线程安全的。您不能从多个线程安全地Add。或者您使用的是stackoverflow.com/a/23108315/34092 之类的东西(在这种情况下它是线程安全的,但仅仅是因为它实际上是单线程)?
  • 你用这些大量的物品做什么?为了向用户展示?还有什么?
  • i guess you dint read full question. Inside each foreach there is some logic (very primitive like comparison) happening 我现在已经多次重新阅读该问题,但找不到说明该问题的文字。你能给我们指出来吗?也许更改问题中的文本颜色/粗体以更好地突出它?

标签: c# loops foreach parallel-processing parallel.foreach


【解决方案1】:

瓶颈可能会添加到vesselList,其中添加可能会阻塞操作。所以其他线程可能会等待其他线程已经将行添加到列表中。

如果您想要精确的结果,请使用一些分析器。

【讨论】:

  • 删除了该行,花费相同的时间
  • 什么是数据源。可以并行化源码吗?
【解决方案2】:

所有工作都发生在Add() 中,假设MTObservableCollection 在该方法中使用某种锁定,所有线程都在相互等待以向列表中添加某些内容。

这听起来不像是可以通过并行化加速的工作。

【讨论】:

    【解决方案3】:

    如果您使用的是 MSSQL,另一种方法是执行 BULK 插入。

    我过去有两种方法:

    1. SqlBulkCopy

    2. 带有Table-Valued Parameters 的存储过程(并从C# 将数据作为DataTable 发送)

    我认为这样会少于一秒。

    【讨论】:

    • 问题中没有提到 SQL。
    • 哦,我以为你是在尝试在某个数据库中插入数据……那么,你为什么不使用 AddRange() 方法呢?
    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 2014-05-04
    相关资源
    最近更新 更多