Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

Simon says...

Szymon Pobiega o architekturze i inżynierii oprogramowania
To O/RM or not to O/RM?
Zdaję sobie sprawę, że postem tym mogę wywołać świętą wojnę religijną, ale - niech tam - zaryzykuje. Do napisania na ten temat skłoniła mnie notatka znaleziona przeze mnie ostatnio w sieci. Notatka ta zajmowała się porównywaniem wydajności EDM (Linq to Entities) z NHibernate. Temat ten był bardzo gorący jakiś czas temu. Teraz nieco ostygł, ale wciąż (teraz pewnie z racji zbliżającego się EDM 2.0) trzyma się nieźle.

No więc do rzeczy: co jest szybsze - EDM czy NHibernate? A może wszystkie O/RM-y są złe i należy używać DataReader-a? A może Linq2SQL jest dobrym kompromisem?

(spoiler space:P)

No więc moim zdaniem pytanie to jest pozbawione sensu. Badanie wydajności NHibernate w porównaniu do EDM jest pozbawione sensu. Porównywanie jakiegokolwiek O/RM-a z DataReader-em jest totalnie pozbawione sensu.

Przecież nikt nie powie klientowi: dostęp do danych tej aplikacji wykonuje 50/500/5000 (niepotrzebne skreślić) operacji na sekundę. Klienta naprawdę nie interesuje, jak wydajna jest jego aplikacja, dopóki jest na tyle wydajna, aby go nie denerwować. Nikt nie bada czy strona WWW przeładowuje się 0,1 czy 0,05 sekundy, chociaż to stuprocentowa różnica.

Tak więc pierwsza moja teza: jeśli Twój system nie jest systemem przetwarzającym dane w masowy sposób, OR/M napewno jest dobrym rozwiązaniem. Zastanówcie się co jest tańsze: zakup dwukrotnie mocniejszej maszyny dla postawienia bazy danych, czy zatrudnienie kilku dodatkowych programistów.

Kolejna kwestia - jeśli już OR/M, to jaki? Dla celów tego pytania potraktujmy Linq2SQL jako ubogiego OR/M-a.

Linq2SQL jest zdecydowanie najszybsze z całej trójki. Szybkość ta jednak ma swoją cenę. Ceną tą jest wymuszenie maksymalnego podobieństwa pomiędzy modelem danych w bazie, a modelem w kodzie: tabele mapowane są jeden-do-jednego z klasami, podobnie (domyślnie) jest z kolumnami i właściwościami. Dzięki temu silnik Linq2SQL może lepiej optymalizować swoje zapytania. Nie musi też wykonywać skomplikowanych transformacji. W bezwględnych liczbach działa najszybciej. Zastanówmy się jednak, co by było gdybyśmy chcieli, w naszej nietrywialnej aplikacji, posiadać skomplikowany obiektowy model domeny. Ale to taki naprawde bogaty. Mapowanie go jeden-do-jeden do tabel może doprowadzić do tego, że, mimo iż pojedyncze zapytania będą realizowane szybko, będzie ich tak dużo i będą tak nieoptymalne (logicznie), że całość działać będzie wolniej, niż gdybyśmy użyli bardziej zaawansowanego OR/M-a.

Teza druga: dobre OR/M-y pozwalają nie tylko na mapowanie danych relacyjnych na obiekty, ale także zapewniaja, że oba modele - relacyjny i obiektowy - będą mogły być zrealizowane zgodnie z najlepszymi praktykami związanymi z ich dziedzinami. Kiepski OR/M (Linq2SQL) wymusza dostosowanie się jednego modelu do drugiego: ucierpi na tym przejrzystość, a może nawet i wydajność.

Na koniec zostawiłem sobie starcie gigantów, czyli EDM vs NHibernate. Z jednej strony bardzo mocne wsparcie Microsoft, z drugiej strony bardzo stabilny produkt open-source. Możliwości obu bibliotek są zbliżone, wydajność także. W tym wypadku moim zdaniem diabeł tkwi w szczegółach. Dwóch konkretnie:
  • Wsparcie dla POCO
  • Dostarczane narzędzie
NHibernate w swej filozofii opiera się na idei persystencji POCO. Dzięki temu naturalne wydaje się podejście z modelowaniem na poziomie kodu (C#) z poźniejszym wygenerowaniem schematu bazy danych. NHibernate zawiera od razu narzędzie, które pozwala na podstawie kodu i mapowań wygenerować automatycznie taki schemat.
Z drugiej strony, EDM nie wspiera POCO. Klasy modelu EDM muszą być albo narysowane, albo wygenerowane na podstawie istniejącej bazy danych. Można nawet napisać klasy modelu EDM "z palca". Fakt, że domyślnie wszystkie dane z kolumn są udostępniane jako publiczne właściwości, pozostaje jednak faktem - klasy EDM są "strukturami na sterydach".
Tak jak pisałem, różnica jest subtelna: nie w tym, na co pozwala dana biblioteka, ale raczej w tym, które podejście jest w niej preferowane. Według mnie definitywnie NHibernate promuje bogaty model domeny, natomiast EDM - model anemiczny, generowany na podstawie tabel. Co jest leszcze? - dopowiedżcie sobie sami:)

Opublikowane 28 maja 2009 18:43 przez simon

Filed under:

Komentarze:

# Simon says... : To O/RM or not to O/RM? @ 28 maja 2009 20:04

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

dotnetomaniak.pl

# re: To O/RM or not to O/RM? @ 28 maja 2009 21:28

@Simon: "Zastanówcie się co jest tańsze: zakup dwukrotnie mocniejszej maszyny dla postawienia bazy danych, czy zatrudnienie kilku dodatkowych programistów." - to wcale nie jest takie oczywiste :-)

brejk

# re: To O/RM or not to O/RM? @ 28 maja 2009 23:45

OK, będzie niemerytorycznie, ale nie mogę się powstrzymać:

"Co jest leszcze?"

...?

apl

# re: To O/RM or not to O/RM? @ 29 maja 2009 09:13

@simon

jesli chodzi o POCO i EDM to wraz z .NET Framework 4.0 tworcy EDM zapowadaja pelne wsparcie dla POCO.

Gutek

# re: To O/RM or not to O/RM? @ 29 maja 2009 09:20

Zgadza się. Kwestia, co rozumieją pod pojęciem "pełne wsparcie". Z postów:

http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx

oraz

http://blogs.msdn.com/adonet/archive/2009/05/28/poco-in-the-entity-framework-part-2-complex-types-deferred-loading-and-explicit-loading.aspx

wynika, że domyślnym zachowaniem będzie jednak generowanie klas Entity, a POCO będzie tylko "ficzerem". Tak jak pisałem, sprawa jest delikatna i wiąże się z tym, co jest preferowane, a nie co jest wspierane.

Dodatkowo w ostatnim poście Ayende

http://ayende.com/Blog/archive/2009/05/29/why-defer-loading-in-entity-framework-isnrsquot-going-to-work.aspx

wskazuje na dziury w podejściu Microsoft to lazy load. Być może się czepia, ale są to dla mnie jakieś znaki...

simon

# re: To O/RM or not to O/RM? @ 29 maja 2009 12:59

Jestem zdecydowanie za NHibernatem i POCO, uzyskujemy czystszy model.

Z pomocą Linq2Sql można również uzyskać czysty model domenowy bez bezpośredniego mapowania tabela<>klasa jednak jakimś kosztem wydajności. Tworzymy model domenowy, oddzielnie model Linq2Sql i np. implementujemy wzorzec repozytorium, który operuje na naszym modelu domenowym. Wewnątrz dane pobrane z Linq2sql mapujemy na nasze obiekty domenowe np:

(from userLinq in UserLinqDataContext.Users where .... select new User { Name = userLinq.Name, .... })

mentat

# re: To O/RM or not to O/RM? @ 29 maja 2009 14:18

@mentat

tylko ze linq2sql idzie w "zapomnienie" przez MS i zostaje to zastapiane EDMem.

Tak tylko informacyjnie.

@simon

rozne podejscia rozne rozwiazania, ja za NHibernate nie przepadem tak samo jak za EDM.

zas w obudwu przypadkach stwierdzam ze ludzie odwalili kawal dobrej roboty zakonczony w rozny sposob.

Poza tym jak sie ostatnio nauczylem najwieksza zaleta nhibernate jest takze jego najwieksza wada: open source. dwoch klientow absolutnie nie zgodzilo sie na wykozystanie rozwiazania open source w krytycznych dla nich projektach - oczywiscie mowie tu o dwoch konkretnych klientach i nie mam namysli wszystkich na swiecie. ale podaje przyklad kiedy to EDM mimo ze pisze sie w nim na zasadach tips & tricks i nie wszystko dziala ma przewage nad NH. Takze kilka innych produktow za ktore trzeba placic a ktorych nazw nie pamietam ale Procent na pewno tak :)

Gutek

Gutek

# re: To O/RM or not to O/RM? @ 29 maja 2009 14:20

Z własnego podwórka.

Kilka lat temu DataReader, sproc i nic więcej.

Od kilku lat OR/M i nic więcej. Była Sooda, a od roku NHibernate.

Nie widzę na obecną chwilę innego OR'Ma pozwalającego na tak swobodne poruszanie się po obiektowym modelu domeny niż NHibernate.

To jest jak z jazdą samochodem. Jak już zaczniesz jeździć to później jest już baaaardzo ciężko zrezygnować. Tylko, że najpierw oczywiśćie trzeba zdać prawko, czyli się nauczyć. Podobnie było ze mną i przgodą z OR/Mami. :)

A EDM od samego początku mi się nie podobał.

dario-g

# LLBLGen Pro – płatny O/R Mapper. Czy warto? @ 8 czerwca 2009 06:47

A cóż to i dlaczegóż to Niedawno Szymon napisał posta o O/R Mapperach . Korzystając z impulsu postanowiłem

. jak .NET by Maciej Aniserowicz

Komentarze anonimowe wyłączone