Parallel.For 与 for 循环
Parallel.For vs for loop
我正在思考 运行 宁并行线程,所以我决定在较小的基础上对其进行测试,然后在我觉得舒服时扩展。我正在让同一个过程与自己作对;一个使用 Parallel.For ,另一个使用基本的 for 循环。我正在捕捉比较的时间(以滴答为单位)。示例代码采用一个数组(在本例中为 53 个两个字符串)并用该数组填充给定的 ListBox
。
对我来说几乎没有意义的是,当我 运行 基本 For 循环时,它平均产生 1,400 个滴答,但是当我 运行 Parallel.For
循环 returns 平均 5,200 个刻度。样本量是否太小以至于平行无效?
这是我使用的两个片段。 Parallel.For
循环是:
public void ListboxFromArray(ListBox listbox, string[] array1)
{
// This method takes an array and fills a listbox full of items from the array
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Parallel.For(0, array1.Count(),
index =>
{
listbox.Items.Add(array1[index]);
});
stopWatch.Stop();
long ts = stopWatch.ElapsedTicks;
string elapsedTime = ts.ToString() + " Ticks"; ;
MessageBox.Show(elapsedTime);
}
并且 for
循环是:
public void ListboxFromArray(ListBox listbox, string[] array1)
{
// This method takes an array and fills a listbox full of items from the array
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < array1.Count(); i++)
{
listbox.Items.Add(array1[i]);
}
stopWatch.Stop();
long ts = stopWatch.ElapsedTicks;
string elapsedTime = ts.ToString() + " Ticks"; ;
MessageBox.Show(elapsedTime);
}
感谢您提前输入或验证我的想法。
我认为您的样本量太小,而且您在循环中所做的工作也太小,无法克服 task/thread 管理的开销。并行计算消耗如此之少的内存操作没有什么意义 CPU。如果您要对 100,000 个项目进行排序,那么也许...
如果您想为集合中的每个项目计算需要花费一些时间来计算的东西,使用 Parallel.For
很有用。
int[] coll = new int[]{10,9,8,7,6,5,4,3,2,1};
Parallel.ForEach(coll,
item=>
{
Thread.Sleep(TimeSpan.FromSeconds(item));
Console.WriteLine(item + "Finished");
});
与顺序方式相比
foreach (var item in coll)
{
Thread.Sleep(TimeSpan.FromSeconds(item));
Console.WriteLine(item + "Finished");
}
第一个代码运行得更快,因为它确实是并行工作。
在您的情况下,如果您只想执行 "no work",那么 thead
中的开销就太大了。
我认为您做不到...首先,您从非UI 线程访问UI 控件(ListBox)。 AFAIK,Parallel.For
不进行任何线程编组以确保安全。其次,您在没有锁定的情况下从多个线程访问同一个集合 (ListBox.Items
) - 同样,不安全。
一般来说,我会说这是 而不是 Parallel.For
的设计目的。您在这里并没有完全成为 I/O 或 CPU 的瓶颈,这意味着任何并行性开销都会使任何可能的改进相形见绌。
我正在思考 运行 宁并行线程,所以我决定在较小的基础上对其进行测试,然后在我觉得舒服时扩展。我正在让同一个过程与自己作对;一个使用 Parallel.For ,另一个使用基本的 for 循环。我正在捕捉比较的时间(以滴答为单位)。示例代码采用一个数组(在本例中为 53 个两个字符串)并用该数组填充给定的 ListBox
。
对我来说几乎没有意义的是,当我 运行 基本 For 循环时,它平均产生 1,400 个滴答,但是当我 运行 Parallel.For
循环 returns 平均 5,200 个刻度。样本量是否太小以至于平行无效?
这是我使用的两个片段。 Parallel.For
循环是:
public void ListboxFromArray(ListBox listbox, string[] array1)
{
// This method takes an array and fills a listbox full of items from the array
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Parallel.For(0, array1.Count(),
index =>
{
listbox.Items.Add(array1[index]);
});
stopWatch.Stop();
long ts = stopWatch.ElapsedTicks;
string elapsedTime = ts.ToString() + " Ticks"; ;
MessageBox.Show(elapsedTime);
}
并且 for
循环是:
public void ListboxFromArray(ListBox listbox, string[] array1)
{
// This method takes an array and fills a listbox full of items from the array
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < array1.Count(); i++)
{
listbox.Items.Add(array1[i]);
}
stopWatch.Stop();
long ts = stopWatch.ElapsedTicks;
string elapsedTime = ts.ToString() + " Ticks"; ;
MessageBox.Show(elapsedTime);
}
感谢您提前输入或验证我的想法。
我认为您的样本量太小,而且您在循环中所做的工作也太小,无法克服 task/thread 管理的开销。并行计算消耗如此之少的内存操作没有什么意义 CPU。如果您要对 100,000 个项目进行排序,那么也许...
如果您想为集合中的每个项目计算需要花费一些时间来计算的东西,使用 Parallel.For
很有用。
int[] coll = new int[]{10,9,8,7,6,5,4,3,2,1};
Parallel.ForEach(coll,
item=>
{
Thread.Sleep(TimeSpan.FromSeconds(item));
Console.WriteLine(item + "Finished");
});
与顺序方式相比
foreach (var item in coll)
{
Thread.Sleep(TimeSpan.FromSeconds(item));
Console.WriteLine(item + "Finished");
}
第一个代码运行得更快,因为它确实是并行工作。
在您的情况下,如果您只想执行 "no work",那么 thead
中的开销就太大了。
我认为您做不到...首先,您从非UI 线程访问UI 控件(ListBox)。 AFAIK,Parallel.For
不进行任何线程编组以确保安全。其次,您在没有锁定的情况下从多个线程访问同一个集合 (ListBox.Items
) - 同样,不安全。
一般来说,我会说这是 而不是 Parallel.For
的设计目的。您在这里并没有完全成为 I/O 或 CPU 的瓶颈,这意味着任何并行性开销都会使任何可能的改进相形见绌。