技術(shù)頻道導(dǎo)航
HTML/CSS
.NET技術(shù)
IIS技術(shù)
PHP技術(shù)
Js/JQuery
Photoshop
Fireworks
服務(wù)器技術(shù)
操作系統(tǒng)
網(wǎng)站運(yùn)營(yíng)

贊助商

分類目錄

贊助商

最新文章

搜索

對(duì)比C# Parallel.ForEach()與foreach()速度快慢

作者:admin    時(shí)間:2023-6-5 14:46:30    瀏覽:

foreach 循環(huán)

C# 中的foreach循環(huán)在單個(gè)線程上運(yùn)行,并且處理一個(gè)接一個(gè)地按順序進(jìn)行。foreach循環(huán)是 C# 的一項(xiàng)基本功能,從 C# 1.0 開(kāi)始提供。在大多數(shù)情況下,它的執(zhí)行速度比 Parallel.Foreach慢。

Parallel.ForEach 循環(huán)

C# 中的 Parallel.ForEach 循環(huán)在多個(gè)線程上運(yùn)行,處理以并行方式進(jìn)行。Parallel.ForEach 循環(huán)不是 C# 的基本功能,它在 C# 4.0 及更高版本中可用。在 C# 4.0 之前我們不能使用它。在大多數(shù)情況下,它的執(zhí)行速度比 foreach 快。要使用 Parallel.ForEach 循環(huán),我們需要在 using 指令中導(dǎo)入System.Threading.Tasks命名空間。

但是你非常了解你的應(yīng)用程序,并且可以決定要使用哪一個(gè)。

我給出了 2 個(gè)示例,在第一個(gè)示例中,傳統(tǒng)的 foreach 循環(huán)比 Parallel.ForEach 循環(huán)更快,而在第二個(gè)示例中,傳統(tǒng)的 foreach 循環(huán)與 Parallel.ForEach 相比非常慢。

示例 1: Parallel.ForEach 循環(huán)比傳統(tǒng)的 foreach 循環(huán)慢。

List<string> fruits = new List<string>();  
  fruits.Add("Apple");  
  fruits.Add("Banana");  
  fruits.Add("Bilberry");  
  fruits.Add("Blackberry");  
  fruits.Add("Blackcurrant");  
  fruits.Add("Blueberry");  
  fruits.Add("Cherry");  
  fruits.Add("Coconut");  
  fruits.Add("Cranberry");  
  fruits.Add("Date");  
  fruits.Add("Fig");  
  fruits.Add("Grape");  
  fruits.Add("Guava");  
  fruits.Add("Jack-fruit");  
  fruits.Add("Kiwi fruit");  
  fruits.Add("Lemon");  
  fruits.Add("Lime");  
  fruits.Add("Lychee");  
  fruits.Add("Mango");  
  fruits.Add("Melon");  
  fruits.Add("Olive");  
  fruits.Add("Orange");  
  fruits.Add("Papaya");  
  fruits.Add("Plum");  
  fruits.Add("Pineapple");  
  fruits.Add("Pomegranate");  
  
  Console.WriteLine("Printing list using foreach loop\n");  
  
  var stopWatch = Stopwatch.StartNew();  
  foreach (string fruit in fruits)  
  {  
      Console.WriteLine("Fruit Name: {0}, Thread Id= {1}", fruit, Thread.CurrentThread.ManagedThreadId);  
  }  
  Console.WriteLine("foreach loop execution time = {0} seconds\n", stopWatch.Elapsed.TotalSeconds);  
  Console.WriteLine("Printing list using Parallel.ForEach");  
  
  
  stopWatch = Stopwatch.StartNew();  
  Parallel.ForEach(fruits, fruit =>  
  {  
      Console.WriteLine("Fruit Name: {0}, Thread Id= {1}", fruit, Thread.CurrentThread.ManagedThreadId);  
  
  }  
  );  
  Console.WriteLine("Parallel.ForEach() execution time = {0} seconds", stopWatch.Elapsed.TotalSeconds);  
  Console.Read();  

輸出

 

 

示例 2:Parallel.ForEach 循環(huán)比傳統(tǒng)的 foreach 循環(huán)更快。

傳統(tǒng)的foreach

var stopWatch = Stopwatch.StartNew();  
PointF firstLocation = new PointF(10 f, 10 f);  
PointF secondLocation = new PointF(10 f, 50 f);  
foreach(string file in Directory.GetFiles(@ "D:\Images"))  
{  
    Bitmap bitmap = (Bitmap) Image.FromFile(file);  
    using(Graphics graphics = Graphics.FromImage(bitmap))  
    {  
        using(Font arialFont = new Font("Arial", 10))  
        {  
            graphics.DrawString("Banketeshvar", arialFont, Brushes.Blue, firstLocation);  
            graphics.DrawString("Narayan", arialFont, Brushes.Red, secondLocation);  
        }  
    }  
    bitmap.Save(Path.GetDirectoryName(file) + "Foreachloop" + "\\" + Path.GetFileNameWithoutExtension(file) + Guid.NewGuid()  
        .ToString() + ".jpg");  
}  
Console.WriteLine("foreach loop execution time = {0} seconds\n", stopWatch.Elapsed.TotalSeconds);  

輸出

 

Parallel.ForEach

var stopWatch = Stopwatch.StartNew();  
PointF firstLocation = new PointF(10 f, 10 f);  
PointF secondLocation = new PointF(10 f, 50 f);  
Parallel.ForEach(Directory.GetFiles(@ "D:\Images"), file =>  
{  
    Bitmap bitmap = (Bitmap) Image.FromFile(file);  
    using(Graphics graphics = Graphics.FromImage(bitmap))  
    {  
        using(Font arialFont = new Font("Arial", 10))  
        {  
            graphics.DrawString("Banketeshvar", arialFont, Brushes.Blue, firstLocation);  
            graphics.DrawString("Narayan", arialFont, Brushes.Red, secondLocation);  
        }  
    }  
    bitmap.Save(Path.GetDirectoryName(file) + "Parallel" + "\\" + Path.GetFileNameWithoutExtension(file) + Guid.NewGuid()  
        .ToString() + ".jpg");  
});  
Console.WriteLine("Parallel.ForEach() execution time = {0} seconds", stopWatch.Elapsed.TotalSeconds);  
Console.Read();  

輸出

 

結(jié)論

為了測(cè)試上述代碼的性能,我在這兩種情況下都使用了大約 150 張圖像。

你可以看到,如果你在 foreach 循環(huán)內(nèi)執(zhí)行任何批量任務(wù),那么 Parallel.ForEach 非常快,因此你可以使用 Parallel.ForEach。

Parallel.ForEach循環(huán)的工作方式類似于Parallel.For循環(huán)。循環(huán)對(duì)源集合進(jìn)行分區(qū),并根據(jù)系統(tǒng)環(huán)境在多個(gè)線程上安排工作。系統(tǒng)上的處理器越多,并行方法運(yùn)行得越快。對(duì)于某些源集合,順序循環(huán)可能更快,具體取決于源的大小和循環(huán)執(zhí)行的工作類型。

如果你只是在循環(huán)內(nèi)迭代并執(zhí)行非常小的任務(wù),那么請(qǐng)使用傳統(tǒng)的for 循環(huán)。

相關(guān)文章

標(biāo)簽: Parallel.ForEach  CSharp  foreach  for  
x
  • 站長(zhǎng)推薦
/* 左側(cè)顯示文章內(nèi)容目錄 */