2017-09-18 1 views
-1

vor kurzem i an einer Anwendung gearbeitet haben, die eine dünne Schicht sein, auf der mehrere Dienste soll, diese Anwendung ist vor allem Abbildungen von verschiedenen Datenformat in ein einheitliches Format zu tun (a viele Abbildungen). Wir verwenden, was ich "linq async" nenne, aber ich würde gerne sehen, ob ich seine Leistung verbessern kann.async erwarten vs parallel vs einzigen Thread-Performance

habe ich ein einfaches Experiment wie folgt

using System; 
using System.Collections.Async; 
using System.Collections.Concurrent; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Net.Http; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int max = 100; 
      int[] input = Enumerable.Range(1, max).ToArray(); 
      Work w = new Work(); 

      // senario 1 
      sw.Restart(); 
      var result1 = input.Select(x => w.LongHoursWork(x)).ToArray(); 
      sw.Stop(); 
      Console.WriteLine($"One Thread: {sw.ElapsedMilliseconds}"); 

      // senario 2 
      sw.Restart(); 
      var result2 = MainAsync(input, w).GetAwaiter().GetResult(); 
      sw.Stop(); 
      Console.WriteLine($"Linq async: {sw.ElapsedMilliseconds}"); 

      // senario 3 
      sw.Restart(); 
      var result3 = input.AsParallel().Select(x => w.LongHoursWork(x)).ToArray(); 
      sw.Stop(); 
      Console.WriteLine($"Parallel: {sw.ElapsedMilliseconds}"); 

      // check result 
      for (int i = 0; i < max; i++) 
      { 
       if(result1[i] == result2[i] && result2[i] == result3[i])// && result4.Contains(result1[i])) 
        continue; 

       throw new ArgumentNullException(); 
      } 

      Console.ReadKey(); 
     } 


     static async Task<string[]> MainAsync(int[] input, Work work) 
     { 
      var result = await Task.WhenAll(input.Select(async x => await work.LongHoursWorkAsync(x))); 
      return result; 
     } 
    } 

    public class Work 
    { 
     public string LongHoursWork(int i) 
     { 
      for (int ix = 0; ix < 100000; ix++) 
      { 
       i += ix; 
      } 
      return i.ToString(); 
     } 

     public async Task<string> LongHoursWorkAsync(int i) 
     { 
      return await Task.FromResult(LongHoursWork(i)); 
     } 
    } 
} 

//execution result: 
//One Thread: 88 
//Linq async: 97 
//Parallel: 59 

// if i change the input array to 600(similar to what i have in production 
// environment) 
// execution result: 
// One Thread: 347 
// Linq async: 292 
// Parallel: 101 

ich die senario2 (Linq async) erwarten mehr oder weniger als senario3 gleich sein sollten (parallel) als senario2 eine Menge Aufgaben zu schaffen und führen sie gleichzeitig. Allerdings sagt mir mein einfaches Experiment, dass ich falsch liege. Senario2 ist mehr oder weniger dasselbe wie senario1. das verwirrt mich sehr und ich habe versucht, viele verwandte Fragen in stackoverflow zu lesen, kann aber keine zufriedene Antwort finden. Bei den meisten Fragen handelt es sich um eine nicht blockierende Benutzeroberfläche, während es sich bei meiner Anwendung um einen Back-End-Dienst handelt. Auch lese ich über linq async wird den Durchsatz für einen Backend-Dienst unter Last verbessern, aber von meinem Experiment nicht überzeugt. Wenn es in der Leistung für einen einzelnen Durchlauf nicht überlegen ist, wie kann es den Durchsatz unter Last verbessern? Auch habe ich festgestellt, dass mehr Element in der Eingabe-Array, die bessere Leistung, die ich von der parallelen Ausführung (Szenario3) erhalten kann. Also möchte ich meine Frage hier stellen.

  1. ist linq async nicht viele Aufgaben erstellen und sie gleichzeitig ausführen? warum sind sie fast gleich wie single thread? Dann, was ist der Sinn der Verwendung von ihnen?
  2. für einen Anruf scheint parallel die schnellste, wie wäre es unter hoher Last? welches ist am schnellsten und warum ??
  3. soll ich Linq Async mit Parallel schreiben? Leistung ist in meinem Fall wichtig
  4. oder eher gibt es irgendwelche Fehler in meinem Experiment ?? Soll ich ein E/A-gebundenes Experiment durchführen?

Vielen Dank im Voraus.

+0

Über Ihre zweite und dritte Frage [lesen] (https://stackoverflow.com/questions/6036120/parallel-foreach-slower-than-foreach) – Ferus7

Antwort

0

Der allgemeine Vorteil von async-await ist nicht Leistung, sondern Reaktionsfähigkeit.

Es geht um den aktuellen Thread Freigabe (der UI-Thread auf dem Client-UIs, die Thread-Pool Gewinde auf ASP.NET), wenn eine Blockierungsoperation (in der Regel, I/O) erfolgt.

Da jedes Mal, wenn der Thread freigegeben wird, gibt es einen Kontextwechsel sowie wenn ein Thread ergriffen wird, um die Ausführung fortzusetzen, hat asynchroner Code ein wenig Aufwand und daher weniger Leistung.

Aber weil es eine bessere Nutzung von Ressourcen fördert, könnte sich das Gesamtsystem leistungsfähiger fühlen, nur weil es reaktionsfähiger ist.

Wenn echte Parallelität möglich ist, dann ist das System leistungsfähiger.

Im Allgemeinen sollten Sie in Bezug auf die Leistung immer Ihren speziellen Anwendungsfall messen.