优化这段代码: var dic = new ConcurrentDictionary<int, int>(); int i = 0; var t1 = Task.Run(() => { Parallel.For(0, 10000, t => { dic.AddOrUpdate(1, t, (k, v) => { i++; return t; }); }); });
时间: 2023-11-20 20:06:22 浏览: 115
可以将Parallel.For改为Parallel.ForEach,并使用局部变量来代替i计数,以避免线程安全问题。同时可以将ConcurrentDictionary改为普通的Dictionary,因为并发字典会对性能有一定的影响。
重构后的代码如下:
```
var dic = new Dictionary<int, int>();
int count = 0;
Parallel.ForEach(Enumerable.Range(0, 10000), () => 0, (i, state, localCount) =>
{
dic.AddOrUpdate(1, i, (k, v) => { localCount++; return i; });
return localCount;
}, (x) => Interlocked.Add(ref count, x));
```
这里使用了Parallel.ForEach的4个参数的重载形式,第一个参数指定迭代范围,第二个参数是初始化本地状态的函数,在本例中不需要,返回值为0即可。第三个参数是每个迭代项执行的操作,其中localCount是每个线程本地的计数器。第四个参数是合并本地状态的函数,用来将所有线程的计数器累加到count变量中。最后使用Interlocked.Add来保证线程安全地累加计数器。
阅读全文