mmofacts.com

LINQ Benchmark

gepostet vor 16 Jahre, 7 Monate von None
Jetzt wo .NET 3.5 mit LINQ raus ist, bin ich neugierig geworden ob LINQ mir Arbeit abnehmen kann.
Da ich z.B. beim Dynamic Data Cache keine Datenbank verwende und den Zugriff auf die gecachten Datenobjekte umständlich programmieren muß, baute ich mir ein Benchmarktool.
Das Tool selbst ist eigenständig zu sehen und war für mich ein Testballon zum Thema LINQ.
Wer mehr darüber lesen will, der kann sich unter dem folgenden Link die Dokumentation, Sourcen und benötigten Dateien herunter laden:
LINQ_Benchmark.zip (224 KB)
Und hier noch kurz das Ergebnis:
Danke übrigens nochmal an TheUndeadable, der mir mit Tips und Korrekturlesen geholfen hat!
gepostet vor 16 Jahre, 7 Monate von BBana
Sehr interessant. Noch schöner wäre es wenn Du noch etwas mehr Details zu den Testfällen geben könntest.
Meine Datenbankklasse basiert derzeit noch auf SQL und beeinhalte auch einige schöne Features (sehr performantes Caching, Relationen jeglicher Kardinalität können in einem Query abgearbeitet werden). LINQ könnte ich mir auch als schöner vorstellen. Nur die Angst vor Performanceverlust hielt mich bisher ab LINQ zu testen. Aber evt. ist das ja unberechtigt und LINQ to SQL wäre denkbar.
gepostet vor 16 Jahre, 7 Monate von TheUndeadable
Es wurde hier nur reines Object-LINQ getestet. Im Archiv findet sich der Sourcecode und ein kleines PDF-Dokument mit einer kurzen, sehr kurzen Beschreibung aller Quellcodes.
DLINQ (LINQ zu SQL) wurde hier absolut nicht getestet, aber in verschiedenen Blogs wurden schon verschiedene Versuche durchgeführt. Da bei einem SQL-Zugriff die größte Zeit sowieso auf Seiten der Datenbank verloren geht und die Datenbank einen reinen SQL-Query empfängt und von LINQ nichts mitbekommt, wurde auch bei verschiedenen Versuchen keinerlei Performanceverlust ermittelt.
Ich persönlich werde bei zukünftigen Projekten nur noch auf DLINQ setzen (soweit ein SQL Server zum Einsatz kommt).
In diesem Blog wird DLINQ behandelt:
blogs.msdn.com/ricom/default.aspx
Den größten Performanceverlust erleidest du, wenn du ein DLINQ-Query mit speziellen Funktionen baust, die nicht in der Datenbank per SQL abgebildet werden können. Dann wird der Query so weit wie möglich optimiert, aber es findet auch noch eine Filterung/Sortierung auf Clientseite statt.
Beispiel:
var ArrayOfX = from x in db.table where x.ToUpper() == "ABC";
Wenn die Datenbank kein ToUpper kennt (bzw der LINQ-Provider dieses nicht umbauen kann), so wird die Filterung zu 100% auf Clientseite durchgeführt. Um dieses Problem zu beobachten hat MS ein paar Events in den LINQ-Providern eingebaut, die abgegriffen werden können.
gepostet vor 16 Jahre, 7 Monate von None
Wie TheUndeadable schon schrieb, ging es mir hauptsächlich um Object-LINQ.
DLINQ steht für mich nicht auf der Checkliste drauf. Grund: Ich kann Datenbanken mit ihren Preisen/Lizenzen nicht mehr sehen. Von daher kommt hier ein eigenes Konstrukt zum Einsatz.
Wenn mich mal wieder die Langeweile kneift, dann geh ich mal den Object-Provider für Dictionaries an. Sofern TheUndeadable nicht wieder schneller war *G*
gepostet vor 16 Jahre, 7 Monate von None
Der LINQ Benchmark hat ein kleines Update erhalten.
Beim Benchmark 2 Run 2 fehlte die Zuweisung zum Objekt. Außerdem werden jetzt noch Zusatzinformationen ausgegeben um eine leichtere Zuordnung zum jeweiligen Abschnitt in der Dokumentation zu ermöglichen.
LINQ_Benchmark.zip (232 KB)
Die Werte haben sich nur geringfügig verändert, was wohl eher an der niedrigeren Grundlast auf der Testmaschine lag. Ansonsten ist die Verteilung gleich geblieben.
gepostet vor 16 Jahre, 7 Monate von KoMtuR
Ich glaube die Zuweisung ist doch egal oder? Immerhin wird ja eine Objektinstanz schon in der Variable cust zugewiesen, oder ist das in C# anders?
Also das ist dann ja nur weiteres rumschupsen von Referenzen Trotzdem ein sehr schöner Test, der wiedermal zeigt, dass nicht alles Gold ist was glänzt und vorallem eigene Entwicklungen immer besser sind, als so ein Framework, was ziemlich allgemein gehalten werden muss.
gepostet vor 16 Jahre, 7 Monate von TheUndeadable
> Also das ist dann ja nur weiteres rumschupsen von Referenzen
Sind immerhin 4 bis 8 Bytes.
> der wiedermal zeigt, dass nicht alles Gold ist was glänzt
Eine Technologie ist nur gut, wenn man weiß wie sie funktioniert und vor allem wenn man weiß wie sie intern funktioniert.
> eigene Entwicklungen immer besser sind, als so ein Framework
Darüber kann man streiten ;-) Aber prinzipiell: Hochoptimierte Spezialfälle sind im Regelfall schneller.
gepostet vor 16 Jahre, 7 Monate von altertoby
also ganz ehrlich ich würde doch nicht auf die Idee kommen anstatt Dictionaries mit LINQ zu durchsuchen nach dem KEY.
Mich würde mehr die Performance-Unterschiede zwischen Delegates, foreach und LINQ interessieren.
Dh. die Customers in ne Liste und die nach bestimmten Kriterien durchsuchen, oder eben die Dictionaries-Values.
Aber wenn es in c# extra ein Konstrukt für den direkten Zugriff auf ein Objekt in einer Sammlung mittels eines Keys gibt, muss ich doch nicht das Rad neu erfinden.
Trotzdem sehr guter Test.
(mich erfreut, dass das 2.2 gegenüber 2.3 nicht alzu viel schneller ist...da das wohl ein allgemeinerer Fall ist wo man LINQ einsetzten kann)
P.s:
Gibts irgendwo nen paar schöne online Ressourcen wie LINQ intern funktioniert?
(schreibt der Compiler die Statements in foreach-Schleifen um?! warum gibts dann zw. 2.2 und 2.3 überhaupt nen Unterschied)
gepostet vor 16 Jahre, 7 Monate von None
Wenn du nen Benchmark dazu machst, dann sag bitte Bescheid!
Würde mich auch interessieren. Bin im Moment nur ein bissle mit meinem Projekt ausgelastet und will da bestimmte Dinge dieses Jahr noch fertig bekommen.
Zu den Internas... da bin ich im Moment auch überfragt. Die mir vorliegenden Unterlagen gehen leider nicht auf die internen Details ein.
*Absenden anklicken und drauf hoffen, das wbb nicht schon wieder mein Posting schluckt*
gepostet vor 16 Jahre, 7 Monate von TheUndeadable
> Mich würde mehr die Performance-Unterschiede zwischen Delegates, foreach und LINQ interessieren.
blog.depon.net/index.php?/archives/187-Traditionell-gegen-funktional.html
Die ersten zwei Benchmarks könnten interessant sein.
Wie LINQ funktioniert:
blog.depon.net/index.php?/archives/253-Noch-schoenerer-Code.html
Code 2, 3 und 4 sind nach der Kompilierung nahezu äquivalent.
Eine wesentlich bessere Quelle:
msdn.microsoft.com/msdnmag/issues/07/06/CSharp30/Default.aspx?loc=de
Dort wird Schritt für Schritt erklärt was LINQ ist und wie es funktioniert. LINQ ist nichts anderes als ein Umschrieb einer SQL-ähnlichen Syntax in Expression-Trees, die sowohl zur Laufzeit als auch vom Compiler in eine anonyme-Deleganten Struktur umgebaut werden kann.
BTW:
Ein Raytracer als LINQ-Statement...
tirania.org/blog/archive/2007/Nov-16.html
gepostet vor 16 Jahre, 7 Monate von altertoby
so hab mal nen bissel geproggt...
als Ergebnis kommt raus, dass LINQ die besten Cache-Möglichkeiten bieten (oder ich LINQ noch nicht kann^^)...bitte überprüft mal jemand was ich da für Grütze geschrieben hab
(List Test, 2. Variante... LINQ um einige 10er Potenzen schneller als alle anderen)
hab leider keinen Server zur Hand wo ich das mal schnell hochladen kann, also hier:
und der Code etwas zu lang fürs Forum ist musste ich mal die Datei zu ner txt Datei machen und hier hochladen...
gepostet vor 16 Jahre, 7 Monate von TheUndeadable
for (int loopCount = 0; loopCount < maxLoop; loopCount++)
{
IEnumerable selectedCust = from cust in customers
where cust.Age > loopCount
select cust;
}

Du musst das LINQ-Statement auch mit einer foreach-Schleife auch ausführen. Das obige Beispiel erzeugt nur das LINQ-Statement, führt aber noch keinerlei Code aus.
Ein Beispiel wäre:
for (int loopCount = 0; loopCount < maxLoop; loopCount++)

{
var oListe = new List( from cust in customers
where cust.Age > loopCount
select cust );
}
gepostet vor 16 Jahre, 6 Monate von altertoby
ah gut... wusste doch, dass es da nen Hacken gibt
also nachdem ich das so kopiert hab:
2 Sekunden langsamer als die anderen Verfahren...
also bei mir war entweder die for-Schleife oder die Delegates die schnellsten...werd ich wohl auch bei den bleiben, da die mit dem (für mich .net 2.0 menschen) ja jetzt auch noch den lambda-operator bekommen haben und somit das dumme Geschreibe großteils wegfällt.

Auf diese Diskussion antworten