2010-12-30 12 views
0

Das Modul, das ich entwickle, macht viele kleine Auswahl, Einfügungen und Updates. Änderungen, die durch Befehle im Namespace SubSonic.Query (ActiveRecord is not my weapon of choice) vorgenommen werden, scheinen wesentlich schneller zu sein als Objekt-für-ID-Auswahlabfragen, die in LINQ geschrieben wurden.SubSonic LINQ-Abfrage ist 3 mal langsamer als SubSonic.Query.Select

Es dauert 7.15s folgende LINQ Abfrage 1000mal

long a = (
    from u in UserCollection 
    where u.UserId == value 
    select u.UserId 
).FirstOrDefault<long>();

Während nur 2.38s für die tausend Läufe von Select Abfrage

long a = new SubSonic.Query.Select(provider, "UserId").From<User>() 
    .Where<User>(x => x.UserId == value).ExecuteScalar<long>();

ich eine Zeit unter der Haube zu schauen nahm auszuführen von LINQ in SubSonic. Der Profiler sagt, dass viel Prozessorzeit von DbQueryProvider.Execute Anrufe in DbQueryProvider.GetExecutionPlan Methode ausgegeben wird - 64%. 22% werden in System.Linq.Expressions.Complie ausgegeben, wenn DbQueryProvider.Execute nur 6% der Zeit verwendet.

Ich bin voll und ganz zufrieden damit, wie SubSonic LINQ-Abfragen analysiert und kompiliert werden. Allerdings wäre es toll, Compilation Anlage Abfragen für repeting SubSonic LINQ zu haben, wie System.Data.Linq.CompiledQuery in Linq2Sql.

+0

Ist es wirklich ein Problem überhaupt? Es scheint nicht zu langsam für einen wirklichen Zweck. – ykatchou

+0

Meinst du eine Web-Anwendung für einen echten Zweck? Das ist ein Problem für mich. Man stelle sich vor, wie lange es dauern würde, 400k Transaktionen kleiner wählt und Einsätze zu machen. Ich muss den Primärschlüssel auswählen, da SubSonic3 das Einfügen + Auswählen nicht zulässt. – Mike

Antwort

0

Wir haben auch einige Profiling auf diese und gefunden SubSonic record.SingleOrDefault (x => x.id = someval) bis zu 20x langsamer als die gleiche Abfrage durch CodingHorror gemacht. Gespeichert hier: https://github.com/subsonic/SubSonic-3.0/issues/258.

Der Profiler auf diese wies in ExecutionBuilder.cs:

// this sucks, but since we don't track true SQL types through the query, and ADO throws exception if you 
// call the wrong accessor, the best we can do is call GetValue and Convert.ChangeType 
Expression value = Expression.Convert(
    Expression.Call(typeof (Convert), "ChangeType", null, 
        Expression.Call(reader, "GetValue", null, Expression.Constant(iOrdinal)), 
        Expression.Constant(TypeHelper.GetNonNullableType(column.Type), typeof(Type)) 
     ), 
    column.Type 
    ); 

Enttäuschend, weil ich wirklich wie SubSonic/Linq.

Am Ende gaben wir auf und ich habe diese - http://www.toptensoftware.com/petapoco. Nach der Portierung zeigte unser Lasttest-Anforderungen pro Sekunde aufgestiegen und CPU-Auslastung von etwa 80% bis 5% gesunken.