【发布时间】:2020-12-18 20:54:45
【问题描述】:
在尝试了解如何使用并行性和并发性时 我在对这些方法进行基准测试时比较了在三种不同方法上花费时间的列表上的登录 但是这三种方法现在让我很困惑:
我在问这段代码是怎么回事?
- 第一种方法是同步
- 第二个方法是同步用作并行
- 第三种方法是异步使用正常循环和 yield
public class LookUpCollections
{
private const int N = 3;
private readonly List<int> _list;
public LookUpCollections()
{
_list = new List<int>();
for (int i = 0; i < N; i++)
{
_list.Add(i);
}
}
[Benchmark]
public void ListLookup() => _list.ForEach(x => Thread.Sleep(TimeSpan.FromSeconds(2)));
[Benchmark]
public void ListLookupAsParallel() => _list.AsParallel<int>().ForAll((x) =>
Thread.Sleep(TimeSpan.FromSeconds(2)));
[Benchmark]
public async IAsyncEnumerable<int> ListLookupAsync()
{
foreach (var item in _list)
{
Task.Delay(TimeSpan.FromSeconds(2)); // the method will complete before 2sec delay
await Task.Delay(TimeSpan.FromSeconds(2)); // some asynchronous work
yield return item;
}
}
}
或者这里是控制台的副本和过去,以防图像出现问题:
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.450
.NET Core SDK=3.1.401
[Host] : .NET Core 2.1.21
DefaultJob : .NET Core 2.1.21
Method Mean Error StdDev
|--------------------- |--------------------:|-----------------:|-----------------:|
| ListLookup | 6,027,116,440.00 ns | 6,926,407.532 ns | 6,478,965.903 ns |
| ListLookupAsParallel | 2,008,655,313.33 ns | 5,275,609.028 ns | 4,934,807.958 ns |
| ListLookupAsync | 27.47 ns | 0.611 ns | 1.632 ns |
LookUpCollections.ListLookupAsync: Default -> 6 outliers were removed (37.39 ns..40.15 ns)
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
1 ns : 1 Nanosecond (0.000000001 sec)
【问题讨论】:
-
您的问题是“这段代码是怎么回事”?你能说得具体点吗?
-
@TheodorZoulias 在我看来,OP 在问为什么这三种方法之间存在如此大的差异。也许是其他 StackOverflow 网站的问题?
-
抱歉有歧义,但我不知道为什么第三种方法最快? ,我希望它会像第二种方法一样在 2 秒后完成
-
你是怎么打电话给
ListLookupAsync的?如果正确等待,大约需要 6 秒才能完成。例如使用await foreach(var i in ListLookupAsync()) { ... }。如果您对某件事进行基准测试,请绝对确保您测量的是正确的。 -
另外,是什么让您认为第三种方法需要 2 秒?它只会连续 3 次依次等待 2 秒。 (未等待的 Task.Delay 是……好吧……毫无意义)
标签: c# collections concurrency async-await task-parallel-library