gpt4 book ai didi

c# - AsParallel() 或异步/等待

转载 作者:行者123 更新时间:2023-11-30 13:56:28 24 4
gpt4 key购买 nike

假设执行一个方法 CountString,给定一个字符串数组和一个 int,返回长度大于该 int 的字符串的数量。如果我必须尽可能利用多核硬件,这样做是否足够:

public int CountString(string[] s, int i) 
{
return s.AsParallel().Count( res => res.length > i);
}

或者我是否必须以某种方式使用 Tasks,甚至混合使用 task 和 PLinq?

只能考虑一个简单的例子,我知道这种方法对硬件性能影响不大。

我想知道这样做是否更好,使用 AsParallel(),还是声明方法 async 并使用 在方法体中等待(即使我不知道如何)。

最佳答案

编辑:

我发现你的实际问题有点误导,我会尝试回答故意的问题。特别是在这里,使用 AsParallel 将是一个很好的方法,因为实际上您不需要await 任何东西。由于您要处理集合,PLINQ 或 Paralle.ForEach 是不错的选择。当您具有自然的异步 I/O 绑定(bind)操作时,请考虑使用 async-await。建议不要wrap synchronous methods with async wrappers.


如果您实际测试您的代码,您甚至可能会惊讶地发现并行这段代码实际上会对您的方法执行产生负面性能成本,具体取决于大小 你正在迭代的数组。

很多时候人们忘记了使用线程实际上是有开销的,即使使用线程池之外的线程也是如此。您必须进行最少的 CPU 密集型工作,这样才值得承受并行化的性能损失。

如果您的数组足够长,那么使用 AsParallel 应该就足够了。没有理由添加 Task,因为 PLINQ 会很好地处理并行化。

好的,让我们实际测试这段代码。我将迭代一个充满 GUID 的 string[]。这是代码:

主要方法:

void Main()
{
//JIT
Test(0);

Test(100);
Test(1000);
Test(10000);
Test(1000000);
Test(10000000);
}

public void Test(int itemAmount)
{
string[] strings = Enumerable.Range(0, itemAmount).Select(i => Guid.NewGuid()
.ToString()).ToArray();

var stopWatch = Stopwatch.StartNew();
CountStringInParallel(strings, itemAmount);
stopWatch.Stop();
Console.WriteLine("Parallel Call: String amount: {0}, Time: {1}",
itemAmount, stopWatch.Elapsed);

stopWatch.Restart();
CountStringSync(strings, itemAmount);
stopWatch.Stop();
Console.WriteLine("Synchronous Call: String amount: {0}, Time: {1}",
itemAmount, stopWatch.Elapsed);
}

并行和同步:

public int CountStringInParallel(string[] s, int i) 
{
return s.AsParallel().Count( res => res.Length > i);
}

public int CountStringSync(string[] s, int i)
{
return s.Count(res => res.Length > i);
}

结果:

Parallel Call: String amount: 100, Time: 00:00:00.0000197

Synchronous Call: String amount: 100, Time: 00:00:00.0000026


Parallel Call: String amount: 1000, Time: 00:00:00.0000266

Synchronous Call: String amount: 1000, Time: 00:00:00.0000201


Parallel Call: String amount: 10000, Time: 00:00:00.0002060

Synchronous Call: String amount: 10000, Time: 00:00:00.0002003


Parallel Call: String amount: 1000000, Time: 00:00:00.0080492

Synchronous Call: String amount: 1000000, Time: 00:00:00.0135279


Parallel Call: String amount: 10000000, Time: 00:00:00.0744104

Synchronous Call: String amount: 10000000, Time: 00:00:00.1402474

可以看到最多10,000个字符串,同步方法实际上比并行方法更快。

关于c# - AsParallel() 或异步/等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28092436/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com