C# 并行。For vs For循环

C# 并行。For vs For循环,c#,for-loop,parallel.for,C#,For Loop,Parallel.for,我正在绕着并行线程运行,所以我决定在一个较小的基础上进行测试,然后在我感到舒服的时候进行扩展。我把同样的过程与自己对立起来;一个使用Parallel.For,另一个使用基本For循环。我正在捕获时间(以滴答为单位)进行比较。示例代码获取一个数组(在本例中为两个字符串),并用该数组填充给定的列表框 对我来说几乎毫无意义的是,当我运行基本For循环时,平均会产生1400个滴答声,但当我并行运行时,对于循环,平均会返回5200个滴答声。样本量是否太小,平行法无法有效 下面是我正在使用的两个片段。并行。

我正在绕着并行线程运行,所以我决定在一个较小的基础上进行测试,然后在我感到舒服的时候进行扩展。我把同样的过程与自己对立起来;一个使用Parallel.For,另一个使用基本For循环。我正在捕获时间(以滴答为单位)进行比较。示例代码获取一个数组(在本例中为两个字符串),并用该数组填充给定的
列表框

对我来说几乎毫无意义的是,当我运行基本For循环时,平均会产生1400个滴答声,但当我并行运行
时,对于
循环,平均会返回5200个滴答声。样本量是否太小,平行法无法有效

下面是我正在使用的两个片段。
并行。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);

}
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);
}
循环的
是:

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);

}
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);
}
public void ListboxFromArray(ListBox ListBox,字符串[]array1)
{
//此方法获取一个数组并填充一个列表框,其中包含该数组中的所有项
秒表秒表=新秒表();
秒表。开始();
对于(int i=0;i

感谢您事先对我的想法进行的任何输入或验证。

我认为您的样本量太小,而且您在循环中所做的工作太小,无法克服任务/线程管理的开销。并行化一个占用如此少CPU的内存中的操作没有什么意义。如果您正在进行100000项排序,那么可能…

我认为您的样本量太小,并且您在循环中所做的工作太小,无法克服任务/线程管理的开销。并行化一个占用如此少CPU的内存中的操作没有什么意义。如果您正在进行100000项排序,则可能…

使用
并行。对于
,如果您要为集合中的每个项计算一些需要花费一定时间的内容,则非常有用

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");
}
第一个代码运行得更快,因为它实际上是并行工作的


在您的情况下,如果您只想执行“不工作”,那么AD中的开销就太大了。

使用
并行。如果您想为集合中的每个项目计算一些需要花费一定时间的东西,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");
}
第一个代码运行得更快,因为它实际上是并行工作的


在您的情况下,如果您只想执行“无工作”,那么AD中的开销就太大了。

我认为您无法做到这一点……首先,您要从非UI线程访问UI控件(列表框)。好吧,
Parallel.For
不做任何线程编组来保证安全。其次,您正在从多个线程访问同一个集合(
ListBox.Items
),而没有锁定-同样,这是不安全的


一般来说,我会说这不是Parallel.For的设计目的。在这里,您并不是在I/O或CPU上遇到瓶颈,这意味着任何并行开销都会使任何可以想象的改进相形见绌。

我认为您无法做到这一点……首先,您是从非UI线程访问UI控件(ListBox)。好吧,
Parallel.For
不做任何线程编组来保证安全。其次,您正在从多个线程访问同一个集合(
ListBox.Items
),而没有锁定-同样,这是不安全的


一般来说,我会说这不是Parallel.For的设计目的。在这里,您并不是在I/O或CPU方面遇到瓶颈,这意味着任何并行开销都将使任何可以想象的改进相形见绌。

谢谢,这正是困扰我的问题。我不是100%确定,但这对我来说也是最有意义的,我只是想听听第二种意见。事实上,这是错误的。他的样本量不是太小——除此之外,他的代码不是线程安全的。此外,我还操纵了一个UI控件,这是不可行的多线程,因此,如果它工作,它会自动编组到一个线程。完全停止测试。@TomTom-这些项只是一个ListBoxObjectCollection,它不是线程安全的(没有任何集合是线程安全的,除非明确设计为线程安全的),但这不会影响测试的性能。同意添加的结果可能没有任何定义的顺序(但这是Parallel.For的预期结果),这不是一个真实的示例,但由于他没有得到异常,因此允许他访问集合-除非您认为Parallel.ForEach“注意到”交叉线程访问控件,然后是单线程。。。。我认为这不太可能。一个糟糕的测试,但是…谢谢,那正是困扰我的。我不是100%确定,但这对我来说也是最有意义的,我只是想听听第二种意见。事实上,这是错误的。他的样本量不是太小——除此之外,他的代码不是线程安全的。此外,我还操纵了一个UI控件,这是不可行的多线程,因此,如果它工作,它会自动编组到一个线程。完全停止测试。@TomTom-这些项只是一个ListBoxObjectCollection,它不是线程安全的(没有任何集合是线程安全的,除非明确设计为线程安全的),但这不会影响测试的性能。同意添加的结果可能没有任何定义的顺序(但这是Parallel.For的预期结果),这不是一个真实的示例,但由于他没有得到异常,因此允许他访问集合-除非您认为Parallel.ForEach“注意到”交叉线程访问控件,然后是单线程。。。。我认为这不太可能。这是一个糟糕的测试,但是……除了执行时间之外,您可能还需要查看最终或最终结果