Запрос SubSonic LINQ в 3 раза медленнее, чем SubSonic.Query.Select - PullRequest
0 голосов
/ 30 декабря 2010

Модуль, который я разрабатываю, делает множество мелких выборок, вставок и обновлений.Модификации, сделанные командами в SubSonic.Query пространстве имен ( ActiveRecord не является моим любимым оружием ), выглядят намного быстрее, чем запросы выбора объекта по идентификатору, написанные в LINQ.

Itтребуется 7,15 с, чтобы выполнить следующий LINQ запрос 1000 раз

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

В то время как всего лишь 2,38 с для тысячи прогонов Select запроса

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

Мне потребовалось время, чтобы посмотретьпод капотом LINQ в SubSonic.Профилировщик говорит, что большая часть процессорного времени вызовов DbQueryProvider.Execute расходуется в методе DbQueryProvider.GetExecutionPlan - 64%.22% тратится в System.Linq.Expressions.Complie, когда DbQueryProvider.Execute использует только 6% времени.

Я полностью удовлетворен тем, как запросы SubSonic LINQ анализируются и компилируются.Однако было бы замечательно иметь средство компиляции для повторения запросов SubSonic LINQ, например System.Data.Linq.CompiledQuery в Linq2Sql.

1 Ответ

0 голосов
/ 22 марта 2011

Мы также провели некоторое профилирование и обнаружили, что запись SubSonic.SingleOrDefault (x => x.id = someval) будет в 20 раз медленнее, чем тот же запрос, выполняемый через CodingHorror.Зарегистрированный здесь: https://github.com/subsonic/SubSonic-3.0/issues/258.

Профилировщик указал на это в 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
    );

Разочаровывает, потому что мне действительно нравится SubSonic / Linq.

В концемы сдались, и я написал это - http://www.toptensoftware.com/petapoco. После портирования наш нагрузочный тест показал, что количество запросов в секунду возрастало, а загрузка процессора снизилась с 80% до 5%.

...