Re[119]: Тормознутость и кривость linq
От: IT Россия linq2db.com
Дата: 23.06.16 15:29
Оценка: +6
Здравствуйте, все.

Ещё раз попытаюсь объяснить где у LINQ могут быть тормоза и насколько они влияют на общую картину.

Что происходит во время LINQ запроса:

1. Компилятор генерирует код для построения ExpressionTree, соответственно при вызове кода оно строится каждый раз при каждом вызове. Т.е. у нас уже появляются накладные расходы, с которыми вообще ничего нельзя поделать. Насколько они влияют на общее время зависит от сложности запроса, но мы видели, что всё в сумме болтается в районе 1%.

2. Далее управление принимает LINQ провайдер, который по полученному ET строит SQL. Здесь всё зависит от радиуса кривизны рук разработчиков. Процесс разбора ET и построение оптимального SQL действительно может оказаться дорогостоящим и самое главное плохо кешируется. Но сильно заметно это только либо на совсем убитом провайдере, либо на очень простых запросах как в тестах, где к томуже полностью исключён код окружения запроса типа стэка ASP.NET, авторизация, логирование, рендеринга и всех остальных прелестей. Тем не менее некачественный LINQ провайдер может здесь существенно натормозить.

3. После построения SQL и его выполнения производится материализация объектов. Вот здесь медленный маппинг может дать замедление в разы при условии, что сам запрос к БД оптимален.

В результате, чтобы получить реально полезную картинку соотношения производительности нужно тестировать не отдельные запросы, а весь стек приложения. Т.е., например, для веб-приложения подёргать странички с разными вариантами запросов. Тогда будет видно, что вменяемый LINQ провайдер даёт замедление на уровне погрешности, а невменяемый заметно тормозит.

Я не говорю, что подобные тесты совсем не нужны, нужны, но нужно и понимать их практическую пользу.

Что касается реально сложных запросов и тем более динамической сборки запросов, то здесь для любителей прямого SQL всё гораздо хуже. LINQ позволяет на порядок проще строить на порядок более оптимальные запросы. На практике для генерации прямого SQL народ либо строит универсальные view, в который вбиты все возможные джоины, либо тупо упирается в сложность, и как результат, в глючность решения. Тогда как при использовании ассоциаций LINQ автоматически строит все нужные джоины, устраняет вещи типа "@p = NULL OR Field1 = @p" и т.п.

Ну и под конец главный козырь LINQ — type safety. Можете мне петь любые песни про любые тормоза, но это преимущество ни много ни мало переводит работу с БД на принципиально другой уровень. Это можно сравнить разве что с переходм от C/C++ модели памяти (предлагаю не начинать обсуждать возможные костыли вроде auto_ptr, я в курсе), где хождение по граблям занимает большую часть времеи, к автоматической сборке, где высвобожденное время можно с успехом потратить, например, на архитектуру приложения и добиться лучшей производительности архитектурными решениями. А это уже может оказаться не 2%, а 2000.
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.