Производительность Entity Framework
От: Степанов Андрей  
Дата: 06.03.12 16:19
Оценка: 2 (1)
Добрый день!
Подумываю над тем, чтобы опробовать какой-нибудь ORM в своем проекте. Реальной необходимости пока не вижу, прекрасно обхожусь запросами к БД, но может быть я слеп, надо изучить область
Так вот решил попробовать Entity Framework. На текущий момент приложению приходится выполнять довольно много мелких запросов (например, по первичному ключу), поэтому я решил проверить скорость выборки данных EF. Вот тестовый код, который сравнивает прямую выборку из БД через ADO.NET и через EF:

// ADO.NET
SqlConnection cnn = new SqlConnection ( @"Data Source=someserver;Initial Catalog=testdb;User ID=sa;Password=hh345;" );
cnn.Open ( );
SqlDataAdapter ad = new SqlDataAdapter ( "select * from hoteldictionary where HD_CNKEY = 1 AND HD_KEY = 232", cnn );
DateTime dtBegin = DateTime.Now;
for ( int i = 0; i < 100; i++ ) {
    DataTable dt = new DataTable ( );
    ad.Fill ( dt );
}
Console.WriteLine ( DateTime.Now.Subtract ( dtBegin ).TotalSeconds );
// EF
ctx.Connection.Open ( );
dtBegin = DateTime.Now;
for ( int i = 0; i < 100; i++ ) {
    var hotels1 = ctx.HotelDictionary.Where ( h => h.HD_CNKEY == 1 && h.HD_KEY == 232 ).Select ( h=> new { h.HD_NAME } ).ToArray ( );
}
Console.WriteLine ( DateTime.Now.Subtract ( dtBegin ).TotalSeconds );


HD_KEY является первичным ключом в небольшой таблице на 2500 записей, так что каждая из выборок возвращает одну запись. Пример результатов запуска:
0,53125
1,171875

Проверял многократно, с разным количеством итераций, но все равно получается, что прямая выборка целой записи из БД в два раза быстрее, чем выборка одной колонки через EF. Если в обоих случаях выбирать одну колонку, то скорость будет больше в три раза. При этом EF генерит примерно такой же запрос, который написан вручную, так что разница во времени выполнения целиком из-за EF. Не особо верится, что копирование данных из результатов запроса в поля объекта занимает столько же, сколько работа сервера по выборке и возвращению данных. В связи с этим возникли вопросы:
1) Действительно разница такая большая, или я в эксперименте что-то упустил?
2) Если действительно скорость отличается заметно, то это проблема только в EF, или другие ORM такие же? Я видел тесты скорости EF vs NHibernate, и там EF побеждал, поэтому не думаю, что выбрал самый плохой продукт для замера скорости.
3) Были ли у кого-нибудь реальные проблемы с нагрузкой на сервер из-за ORMов вообще и EF в частности? Если бы мне не приходилось делать много мелких запросов к базе, я бы даже не задумывался над этим — удобство наверняка превысит небольшое падение производительности. Но мне приходится.
Re: Производительность Entity Framework
От: stasal Россия  
Дата: 06.03.12 16:39
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:
СА>// EF
СА>ctx.Connection.Open ( );
СА>dtBegin = DateTime.Now;
СА>for ( int i = 0; i < 100; i++ ) {
СА> var hotels1 = ctx.HotelDictionary.Where ( h => h.HD_CNKEY == 1 && h.HD_KEY == 232 ).Select ( h=> new { h.HD_NAME } ).ToArray ( );
СА>}
СА>Console.WriteLine ( DateTime.Now.Subtract ( dtBegin ).TotalSeconds );

А если избавиться от этой сложной лямбды в цикле и написать что-то вроде:

ctx.HotelDictionary.Load();
var hotels1 = from hd in ctx.HotelDictionary.Local
              where hd.HD_CNKEY == 1 and hd.HD_KEY == 232
              select hd;

Сразу оговорюсь: я не спец по EF, не знаю, превратится ли этот код во что-то более быстрое, просто интересно, а вдруг
Re: Производительность Entity Framework
От: Elderos Россия  
Дата: 06.03.12 17:35
Оценка: +2
Здравствуйте, Степанов Андрей, Вы писали:

СА>1) Действительно разница такая большая, или я в эксперименте что-то упустил?

Да, разница большая. Где-то больше, где-то меньше.

СА>2) Если действительно скорость отличается заметно, то это проблема только в EF, или другие ORM такие же? Я видел тесты скорости EF vs NHibernate, и там EF побеждал, поэтому не думаю, что выбрал самый плохой продукт для замера скорости.

EF очень тормозной. BLToolkit, например, на порядок быстрее, но и концепция у него другая.

СА>3) Были ли у кого-нибудь реальные проблемы с нагрузкой на сервер из-за ORMов вообще и EF в частности? Если бы мне не приходилось делать много мелких запросов к базе, я бы даже не задумывался над этим — удобство наверняка превысит небольшое падение производительности. Но мне приходится.

Лично мой опыт убедил меня в том, что для большинства случаев ORM'ы не нужны вообще, от них больше проблем, чем пользы.
Каждый раз приходится смотреть:
и т.д. В общем, надо досконально знать возможности и кишки ORM, чтобы им безболезненно пользоваться.
В результате использую самую простую функциональность BLToolkit, где я сам контролирую запросы (т.е. BLToolkit просто устраняет небольшую рутину, которую постоянно приходится писать в ADO.NET).
Re: Производительность Entity Framework
От: Visor2004  
Дата: 06.03.12 17:54
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:


Используйте BLToolkit, учитывая ваш предыдущий опыт, думаю он вам понравится.
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re: Производительность Entity Framework
От: TK Лес кывт.рф
Дата: 06.03.12 20:13
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:

СА>1) Действительно разница такая большая, или я в эксперименте что-то упустил?


Смотрите на это с другой стороны. Вы реально собираетесь менять 2500 объектов? Если нет, то можно "отключать" объект от EF сразу после материализации.

PS
Результаты тестов лучше смотреть на "втором" проходе
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Производительность Entity Framework
От: Lloyd Россия  
Дата: 06.03.12 20:30
Оценка:
Здравствуйте, stasal, Вы писали:

S>А если избавиться от этой сложной лямбды в цикле и написать что-то вроде:


S>
S>ctx.HotelDictionary.Load();
S>var hotels1 = from hd in ctx.HotelDictionary.Local
S>              where hd.HD_CNKEY == 1 and hd.HD_KEY == 232
S>              select hd;
S>


Ваше выражение компилятов перепишет ровно в такое же (за исключением .ToArray), как и у топикстартера.
Re: Производительность Entity Framework
От: Lloyd Россия  
Дата: 06.03.12 20:33
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:

СА>Проверял многократно, с разным количеством итераций, но все равно получается, что прямая выборка целой записи из БД в два раза быстрее, чем выборка одной колонки через EF. Если в обоих случаях выбирать одну колонку, то скорость будет больше в три раза. При этом EF генерит примерно такой же запрос, который написан вручную, так что разница во времени выполнения целиком из-за EF. Не особо верится, что копирование данных из результатов запроса в поля объекта занимает столько же, сколько работа сервера по выборке и возвращению данных. В связи с этим возникли вопросы:

СА>1) Действительно разница такая большая, или я в эксперименте что-то упустил?

Конкретно для этого примера скорость можно слегка улучшить, если воспользваться Compiled Queries.
Re: Производительность Entity Framework
От: Doc Россия http://andrey.moveax.ru
Дата: 07.03.12 01:51
Оценка: 6 (1)
Здравствуйте, Степанов Андрей, Вы писали:

СА>Проверял многократно, с разным количеством итераций, но все равно получается, что прямая выборка целой записи из БД в два раза быстрее, чем выборка одной колонки через EF.


Версию EF брали 4.х под NET4? Для сравнения:
http://blogs.msdn.com/b/adonet/archive/2012/02/14/sneak-preview-entity-framework-5-0-performance-improvements.aspx

Кроме того, справедливости ради, в реальной более менее серьезной программе вы скорее всего будете использовать конкретные классы данных, а не обращение по индексу к таблице. Поэтому добавьте в тест скорости SQL варианта создание создание массива объектов и перенос туда данных из DataTable. Т.е. что выход обоих тестов был одинаковый по типу.
Re: Производительность Entity Framework
От: hardcase Пират http://nemerle.org
Дата: 07.03.12 09:56
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:

СА>Добрый день!

СА>Подумываю над тем, чтобы опробовать какой-нибудь ORM в своем проекте. Реальной необходимости пока не вижу, прекрасно обхожусь запросами к БД, но может быть я слеп, надо изучить область

Забеги разного рода ORM-ов смотрите на www.ormeter.net.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Производительность Entity Framework
От: IT Россия linq2db.com
Дата: 07.03.12 19:06
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:

СА>2) Если действительно скорость отличается заметно, то это проблема только в EF, или другие ORM такие же? Я видел тесты скорости EF vs NHibernate, и там EF побеждал, поэтому не думаю, что выбрал самый плохой продукт для замера скорости.

СА>3) Были ли у кого-нибудь реальные проблемы с нагрузкой на сервер из-за ORMов вообще и EF в частности?

Есть мнение, что идея ORM себя исчерпала.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Производительность Entity Framework
От: QrystaL Украина  
Дата: 07.03.12 20:46
Оценка:
Здравствуйте, IT, Вы писали:
IT>Есть мнение, что идея ORM себя исчерпала.

А можно подробнее?
Re[3]: Производительность Entity Framework
От: IT Россия linq2db.com
Дата: 07.03.12 21:04
Оценка: 5 (1)
Здравствуйте, QrystaL, Вы писали:

IT>>Есть мнение, что идея ORM себя исчерпала.

QL>А можно подробнее?

Идея жирных ORM — это представление модели данных приложения в виде виртуальной объектной БД, которая одновременно является объектной моделью приложения со встроенным свойством автоматической персистентности. Если посмотреть на современные фреймворки/паттерны потребители таких моделей данных (ASP.NET MVC и MVVM), то отчётливо видно, что в них отказываются от такого подхода. Модели строятся для каждого View, где модель данных используется лишь частично и то по принципу зачем писать два раза то, что уже один раз сгенерировано из схемы БД. Работа с самой БД организуется как с персистентным объектным хранилищем, а как простые функции загрузки и сохранения данных.

Т.е. практика показывает, что идея персистентности оказалось несостоятельной, а вместе с ней и идея жирных ORM.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Производительность Entity Framework
От: Doc Россия http://andrey.moveax.ru
Дата: 08.03.12 02:46
Оценка:
Здравствуйте, IT, Вы писали:

IT>Т.е. практика показывает, что идея персистентности оказалось несостоятельной, а вместе с ней и идея жирных ORM.


ASP.NET MVC (приведенная вами как пример) отлично работает в паре с EF. Более того, проект по умолчанию уже содержит EF.
Re[4]: Производительность Entity Framework
От: matumba  
Дата: 08.03.12 09:18
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, QrystaL, Вы писали:


IT>Работа с самой БД организуется как с персистентным объектным хранилищем, а как простые функции загрузки и сохранения данных.


"Я извиняюсь!..."(ц) А в чём отличие "персистентности" от "загрузки/сохранения"?

В целом, мысль поддерживаю: становиться "гуру" не пойми чего, да ещё написанного не пойми кем — ссыкотно, это вам не библиотечка JSON! Времени угрохаешь немало.
+100 к озвученному BLToolkit. И как у Elderos, у меня БЛТ "устраняет небольшую рутину": все запросы — руками, БЛТ мапит на объекты, работа с объектами, сохренение средствами БЛТ. Каждая строка кода полностью себя описывает.
Re: Производительность Entity Framework
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.03.12 09:54
Оценка:
Здравствуйте, Степанов Андрей, Вы писали:

СА>Проверял многократно, с разным количеством итераций, но все равно получается, что прямая выборка целой записи из БД в два раза быстрее, чем выборка одной колонки через EF. Если в обоих случаях выбирать одну колонку, то скорость будет больше в три раза. При этом EF генерит примерно такой же запрос, который написан вручную, так что разница во времени выполнения целиком из-за EF. Не особо верится, что копирование данных из результатов запроса в поля объекта занимает столько же, сколько работа сервера по выборке и возвращению данных. В связи с этим возникли вопросы:

СА>1) Действительно разница такая большая, или я в эксперименте что-то упустил?
Упустил. Ты померил в цикле компиляцию лямбды. Это долгая операция, ускорить вполне можно с помощью компиляции запросов.
http://msdn.microsoft.com/en-us/library/bb896297.aspx

Для простых запросов работает хорошо. Для сложных запросов, которые динамически строятся во время исполнения — не нужно.


СА>2) Если действительно скорость отличается заметно, то это проблема только в EF, или другие ORM такие же? Я видел тесты скорости EF vs NHibernate, и там EF побеждал, поэтому не думаю, что выбрал самый плохой продукт для замера скорости.

Все orm, поддерживающие Linq относительно долго компилируют запросы. Ef еще не самый худший вариант.

СА>3) Были ли у кого-нибудь реальные проблемы с нагрузкой на сервер из-за ORMов вообще и EF в частности? Если бы мне не приходилось делать много мелких запросов к базе, я бы даже не задумывался над этим — удобство наверняка превысит небольшое падение производительности. Но мне приходится.


Лучше прогони профайлером и посмотри какую часть компиляция лямбд занимает от общего времени работы.

То есть вместо синтетических тестов, сделай веб-приложение с sqlclient\ef и померяй его быстродействие. Я еще давно подобное делал, получилось около 8 на локальной машине. Это без кеширования. Прикрутив грамотное кеширование станет еще меньше.
Re[5]: Производительность Entity Framework
От: IT Россия linq2db.com
Дата: 08.03.12 14:28
Оценка:
Здравствуйте, Doc, Вы писали:

IT>>Т.е. практика показывает, что идея персистентности оказалось несостоятельной, а вместе с ней и идея жирных ORM.

Doc>ASP.NET MVC (приведенная вами как пример) отлично работает в паре с EF. Более того, проект по умолчанию уже содержит EF.

Работает в паре не означает использует все возможности.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Производительность Entity Framework
От: IT Россия linq2db.com
Дата: 08.03.12 14:40
Оценка:
Здравствуйте, matumba, Вы писали:

IT>>Работа с самой БД организуется как с персистентным объектным хранилищем, а как простые функции загрузки и сохранения данных.

M>"Я извиняюсь!..."(ц) А в чём отличие "персистентности" от "загрузки/сохранения"?

В "персистентности" загрузка/сохранение — это лишь малая часть. Плюс к этому мы получаем UoW, change racking, object identity и другие entity services, которые по назначению не используются, но с аппетитом пожирают производительность приложения.
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.