재우니의 블로그

 

Foreach 루프

 

C#의 Foreach loop 는 단일 스레드에서 실행되며 처리는 하나씩 순차적으로 발생합니다. Foreach loop 는 C#의 기본 기능이며 C# 1.0부터 사용할 수 있습니다. 실행은 대부분의 경우  Parallel.Foreach 보다 느립니다 .

 

Parallel.ForEach 

 

C#의 Parallel.ForEach loop 는 멀티 스레드에서 실행되며 처리는 병렬 방식으로 발생합니. Parallel.ForEach loop 는 C#의 기본 기능이 아니며 C# 4.0 이상에서 사용할 수 있습니다. C# 4.0 이전에는 사용할 수 없습니다.

 

대부분의 경우 foreach보다 빠릅니다. Parallel.ForEach 루프를 사용하려면 using 지시문에서 System.Threading.Tasks 네임스페이스 를 가져와야 합니다 .

 

두 가지 예를 제시하고 있습니다.
 
첫 번째 예에서 foreach loop 는 Parallel.foreach loop 보다 빠르며,
두 번째 예에서와 같이 전통적인 foreach 루프는 Parallel.foreach에 비해 매우 느립니다.
 
 

예 1: Parallel.ForEach Loop 는 기존 Foreach Loop 보다 느립니다.

 
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 Loop는 기존 Foreach Loop 보다 빠릅니다.

 

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

 

 

Foreach 구문 실행결과 :

 

 

 

 

 

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

 

 

 

 

Parallel.foreach 구문 결과

 
 
 
 
위 코드의 성능을 테스트하기 위해 두 경우 모두 약 150개의 이미지를 사용했습니다.
 
foreach loop 내에서 대량 작업을 수행하는 경우 parallel.foreach가 매우 빠르므로 parallel.foreach로 이동할 수 있습니다. 그러나 loop 내에서 아주 작은 작업을 반복하고 수행하는 경우에는 for 문의 loop 로 이동 합니다 .
 
 
처리해야 되는 데이터양이 적거나 프로세스가 짧은 경우에 있어서는 순차 처리가 병렬 처리보다 더 빠를 수도 있습니다.
이는 병렬 처리를 위해 처리를 분할하는 과정에서 발생하는 시간 차이입니다.
 
 
고로, Parallel.For 문과 Parallel.ForEach 문은 어떠한 규모의 데이터나 프로세스를 처리하는가에 따라서 적절하게 활용하는 것이 중요합니다.
 
 
 
발췌사이트
 
 

Parallel.ForEach() Vs Foreach() Loop in C#

In this article you will learn about the difference between Parallel.ForEach() Vs Foreach() loop in C# language.

www.c-sharpcorner.com

https://brunch.co.kr/@searphiel9/363