3

我正在这样做:

    private static void Main(string[] args)
    {
        var dict1 = new Dictionary<int, string>();
        var dict2 = new Dictionary<int, string>();
        DateTime t1 = DateTime.Now;
        for (int i = 1; i < 1000000; i++)
        {
            Parallel.Invoke(
                  () => dict1.Add(i, "Test" + i), 
                  () => dict2.Add(i, "Test" + i) );
        }
        TimeSpan t2 = DateTime.Now.Subtract(t1);

        Console.WriteLine(t2.TotalMilliseconds);

        Console.ReadLine();
    }

所以做一个 for 循环 100 万次并将项目​​添加到两个不同的字典中。问题是它需要 11 秒,是仅需要 2 秒的正常顺序方法(没有任务/线程)的 5 倍多。不知道为什么。

4

5 回答 5

10

就像其他人所说或暗示的那样,由于并行化的开销,并行代码并不总是更快。

话虽如此,您的代码将一个项目并行添加到 2 个字典 1M 次,而您应该将 1M 项目并行添加到 2 个字典。差异是微妙的,但最终结果是(在我的机器上)比您的顺序案例快约 10% 的代码。

Parallel.Invoke(() => FillDictionary(dict1, 1000000), () => FillDictionary(dict2, 1000000));

...

private static void FillDictionary(Dictionary<int, string> toFill, int itemCount)
{
    for(int i = 0 ; i < itemCount; i++)
        toFill.Add(i, "test" + i);
}
于 2012-05-29T15:56:35.793 回答
6

使用并行调用存在一定的开销,并且在多个内核/CPU 之间分配工作的好处。在这种情况下,开销大于分配有用工作的实际收益,这就是您看到显着差异的原因。尝试使用更繁重的操作,您将看到不同之处。

于 2012-05-29T15:43:13.247 回答
5

将其重写为:

Parallel.Invoke(
    () =>
    {
        for (int i = 0; i < 1000000; i++)
        {
            dict1.Add(i, "Test" + i);
        }
    },
    () =>
    {
        for (int i = 0; i < 1000000; i++)
        {
            dict2.Add(i, "Test" + i);
        }
    }
);

这应该会快很多,因为这两个线程只被初始化一次,然后运行完成。在您的版本中,您将调用每个 lambda 表达式 1000000 次,每次都等待两者都完成,然后再继续。

Parallel.Invoke真的是为了用于长时间运行的操作。否则,设置并行任务并等待它们全部完成的开销只会扼杀并行运行任务所获得的任何性能。

于 2012-05-29T15:59:19.260 回答
1

Parallel.Invoke意思是“执行所有这些任务并等待它们完成”。在这种情况下,您只会并行执行两个任务。因此,并行调用的开销大于并发的潜在收益。

于 2012-05-29T15:44:56.860 回答
0

如果您要做的是将 100000 个项目添加到两个不同的字典中,那么您应该打破任务之间的工作量,而不是方法。此方法与您的代码相同,但在我的机器上比您的实现要快得多:

var dict1 = new ConcurrentDictionary<int, string>();
    var dict2 = new ConcurrentDictionary<int, string>();

    Parallel.Invoke(() =>
    {
        for(int i = 0; i < 500000; i++)
        {
            dict1[i] = "Test" +i;
            dict2[i] ="Test" +i;
        }
    },
    () =>
    {
        for(int i = 500000; i < 1000000; i++)
        {
            dict1[i] ="Test" +i;
            dict2[i] = "Test" +i;
        }
    });
于 2012-05-29T16:01:14.373 回答