2016-04-01 19 views
0

Ich benutze den ternären Operator, aber es hat große Leistungsineffizienzen Gibt es eine äquivalente Lösung, um die Ineffizienz zu lösen?C# Ternärer Operator?: Effizienz

haben wir zwei Listen gegeben und wir wollen von einem wählen Linq mit:

var myList1 = new List<string>(); 
var myList2 = new List<string>(); 

var result = 
     myList1.Select(x => new { 
     Id = x, 
     Count = myList2.Count(y => y == x) == 0 ? "Not Found" 
               : myList2.Count(y => y == x).ToString() 
     }); 

Jetzt mit dem ternären Operator:? Ich habe hier der Linq Ausdruck gezeigt überprüft, ob die Zählung 0 erste und Display "Not Found", sonst wird die Linq-Zählung erneut ausgeführt und das Ergebnis angezeigt. Mein Punkt ist, dass es die Linq Abfrage zweimal ausführen wird, wenn es effektiv nur den Wert speichern und in dem Else erneut verwenden muss. Dies scheint sehr ineffizient zu sein, wenn die linq-Abfrage etwas größer und komplexer ist.

Ich weiß, dass der ternäre Operator nur für einfache Gleichungen verwendet werden sollte, z. ich> 1? true: false, aber was ist eine Alternative, dies in einer linq-Abfrage zu haben, da ich den Wert nicht zuerst speichern kann, um ihn erneut zu verwenden.

Update:

Dies ist eine theoretische Frage in Bezug auf dem ternären Operator gegeben, dass es die gleiche Gleichung zweimal ausgeführt werden muss, wenn die Bedingung zutrifft. Zu ineffizient, wenn die Gleichung groß und komplex ist?

+4

Heißt das auch kompilieren? Ihr bedingter Operator gibt entweder eine 'int' oder eine 'string' zurück. – juharr

+4

Es ist nicht der ternäre Operator, der langsam ist. – Dismissile

+0

Perforamance Ineffizienz ist wegen '' myList2.Count (y => y == x) '' ändern Sie es in '' myList2.Where (y => y == x) .Count() ' –

Antwort

7

Sie können auch diese mit Hilfe von Abfragesyntax Vorteil let Klausel Einnahme tun:

var result = from e in myList1 
      let count = myList2.Count(y => y == e) 
      select new { Count = count == 0 ? "Not Found" : count.ToString()}; 
+0

Dies ist eine gute Antwort zu verwenden "lassen". –

+0

@JamesDev Dies ist in der Tat eine allgemeinere Herangehensweise, da sie auch auf 'IQueryable's anwendbar ist. Aber für 'IEnumerable's ist die andere Antwort etwas effizienter, weil sie die Zwischenprojektion vermeidet. Ich habe beide :) –

12

ich zum ersten Mal den Wert nicht speichern kann wieder

verwenden Warum nicht? Das kannst du wirklich.

+0

Ich hatte keine Ahnung, dass man Variablen in einem Lambda so deklarieren kann, sehr schön. –

+0

Große Antwort Ich wusste das auch nie. Ich denke, "Let" oder die entsprechende Auswahl in der Lambda-Abfrage ist der Weg zu gehen. –

1

Sie können das Zählergebnis in einer Variablen belassen, sodass Sie für jede Zeile in myList1 nicht 2 Mal zählen. Code:

var myList1 = new List<string>(); 
var myList2 = new List<string>(); 
int counter = 0; 
var result = 
     myList1.Select(x => new { 
      Id = x 
      Count = (counter = myList2.Count(y => y == x)) == 0 ? "Not Found" : counter.ToString() 
     }); 
Verwandte Themen