Alternatywne składniki railsów a wydajność

Witam,
pytanie moje dotyczy tego, czy (a bardziej, czy na tyle dużo, że warto się w to bawić) można zyskać na zasobach/czasie wykonywania skryptu wymieniając pewne składniki aplikacji na inne (i jeśli tak, to prosiłbym o komentarz do moich ewentualnych wyborów)

  1. ORM: DataMapper - raz, że jego składnia (imho) wygląda na poprostu przyjemniejszą w porównaniu z AR, to na dodatek wyczytałem, że jest szybszy od AR)
  2. Szablony: Erubis - chwalą się naprawdę niezłą wydajnością w stosunku do erba, a składnia w zasadzie ta sama
  3. Baza danych: sqlite - tutaj już wybiegam tak naprawdę poza elementy aplikacji w sensie stricte, ale jednak bądź co bądź to również ważny wybór z zakresu wydajności, ale i (jak nie przede wszystkim) możliwości aplikacji. Ogólnie rzecz biorąc, to pod względem skomplikowania projekt, który piszę, nie jest skomplikowany, dlatego nie potrzebuję np. bazy danych, która umożliwia podniecanie się kosmicznie zakręconym zapytaniem, którego i tak nie wykorzystam nigdy - tu mi zależy właściwie tylko na szybkości. Czy można jeszcze jakieś elementy aplikacji zamienić na inne(które nie skutkują automatycznie strzałem w stopę), które poprawiają wydajność?
    Z góry dziękuję za wszelkie konkretne odpowiedzi :wink:
  1. nie jest (tutaj podpytaj Drogomira, on wykonał dobry risercz na temat)
  2. benchmarki proszę, bo chwalić bez dowodów to ja się mogę posunięciem Megan Fox :wink:
  3. nie jest szybsza od mysql nawet w prostych przypadkach

Poprawienie wydajności? Ruby 1.9 (ok, może niedługo, bo na razie nieużywalny z Railsami za bardzo), cache’owanie, cache’owanie i… cache’owanie. Niegłupi kod też można dopisać :wink:

ad 2. http://www.kuwata-lab.com/erubis/users-guide.06.html#topics-benchmark nie wiem na ile to prawda, stąd też moje pytanie do Was :wink:
co co cachowania - to spodziewalem sie takiej odpowiedzi, ktora jest jak najbardziej sensowna :wink: natomiast szukam zamienników do tej układanki, żeby dało radę sprawić, że lokomotywa będzie lżejsza;)

  1. Tak jak Tomash napisał bawiłem się benchmarkami z datamappera: http://www.rubyonrails.pl/forum/p7273-2008-11-22-22%3A31%3A35#p7273 , pastie z wynikami tutaj: http://pastie.org/320883 . Wychodzi, że jest 2 razy szybszy, ale to tylko marketing, najważniejsze według mnie operacje (selecty), są w tych benchmarkach mniej więcej takie same. Mój benchmark był puszczony na postgresie, ten oficjalny na mysqlu.
  2. Używałem w jednym projekcie erubis. Rzeczywiście było trochę szybciej (niestety nie mam żadnych benchmarków, ale testowałem ab2), ale nie wiem jak to teraz wygląda. Najlepiej weź którąś aplikację i puść na erbie, a później na erubisie ab2 i zobacz jak to wygląda. Erubis ma jedną fajną opcję - można go tak ustawić, żeby domyślnie escape’ował tagi htmla.
  3. Też nie sądzę, żeby sqlite była szybsza, ale w wypadku bazy danych używając orma możesz dość łatwo się o tym przekonać - dopóki nie wrzucasz specyficznego dla konkretnej bazy SQLa, możesz łatwo przełączyć się między bazami i sprawdzić jaka jest realna różnica.

Podpisuję się pod tym co napisał Tomash. W większości wypadków problemy z aplikacjami internetowymi to złe zaprojektowanie i problemy wydajności z bazą danych - czyli naucz się o tym jak się cache’uje. W razie czego są też pluginy, które w przypadku dużego obciążenia (jakiś digg effect czy coś) cache’ują wybrane elementy - to jest fajne jeżeli masz dużo dynamicznych elementów, których nie chcesz cashować, a boisz się jakichś skoków obciążenia.

Benchmarki oparte na DM z gemow mozna uznac za historie, DM jest w trakcie sporego refactoringu i optymalizacji, w chwili obecnej performance.rb na postgresie zwraca taki wynik, takze 3.9 szybciej niz AR, bedzie jeszcze lepiej jak rectoring dobiegnie konca.

Marketingiem tez bym tego nie nazwal, poniewaz jezeli taki Model#create wykonuje sie ponad 2 x szybciej niz w przypadku AR to ma to bezposredni i realny wplyw na wydajnosc naszej aplikacji.

Oczywiście, że ma ale ja podobnie jak drogus nie przykładam większego znaczenia do tego, że proste #create jest 2 razy szybsze. O wiele większe znaczenie z reguły mają selecty ponieważ przeciętnie rzecz biorąc w statystycznej aplikacji wykonywane są kilkaset/kilka tysięcy razy większą ilość razy(przeciętna aplikacja webowa gdzie read jest o wiele częstszy niż create/update), a tu jest już o wiele gorzej (Model.all with relationships) DM 3 razy wolniej od AR.

Nie przykładam też większego znaczenia do szybkości danego ORM’a ponieważ tam z reguły nie powstają wąskie gardła. Po prostu prawdopodobieństwo tego że w aplikacji wystąpi wąskie gardło związane z serializowaniem obiektów Rubiego do SQL’a i z powrotem jest o wiele mniejsze niż tego że wąskie gardło wystąpi z braku optymalizacji samego zapytania SQL czy braku indeksu na danej kolumnie czy nawet nie skorzystania z cache.

Tu jest podobnie jak z mikrobenchmarkami różnych implementacji Rubiego, w mikrobenchmarku JRuby/1.9 jest z reguły kilkakrotnie szybszy od 1.8 ale już benchmarkowanie wydajności Rails na 1.9/JRuby nie przynosi podobnych korzyści.

Dla mnie np. o wiele większe znaczenie ma fakt że DM tak naprawdę to “wczesna beta” - potrzeba jeszcze trochę czasu zanim będzie tego można używać w pełni.

Abstrahując już od aplikacji railsowych, gdzie oczywiście masz rację (renderowanie/parsowanie szablonów też zajmuje kupę czasu), to jednak czasem boli przeczołganie profilerem jakiegoś skryptu korzystającego z AR (z reguły tych samych modeli co nasza aplikacja railsowa - mówię o skryptach “towarzyszących”). Boli dlatego, że nierzadko okazuje się, że 80% czasu procesora zabiera samo opakowanie danych z bazy w modele AR (find/SELECT).

Natomiast jeśli ktoś twierdzi, że to wybór konkretnego ORMa jest odpowiedzialny za powolność jego aplikacji, to znaczy że jest kretynem zasługującym na wbicie wiedzy o i umiejętności korzystania z profilera młotkiem do głowy oraz takież samo oduczenie ślepej wiary we wszystko, co się przeczyta w tekstach marketingowych klepanych przez fanboyów :wink:

E, to nie tak - każda baza wymaga tuningu pod konkretną aplikację. Nie wystarczy zmienić drivera w konfigu, puścić rake db:migrate i zapuścić benchmark. W ten sposób sprawdzisz czy na losowej konfiguracji bazy A aplikacja jest szybsza niż na losowej konfiguracji bazy B. I można dojść do zaskakujących wniosków.
Osobiście uważam, że aplikacjie intensywnie korzystające z bazy danych nie mogą być pisane w całkowitym oderwaniu od rodzaju bazy - najlepiej nastawić się na początku na taką, która dobrze się zna, i która potrafi się w razie potrzeby podstroić i zoptymalizować. Ewentualnie taką, od której dobry fachowiec jest pod ręką.

Oczywiście, że ma ale ja podobnie jak drogus nie przykładam większego znaczenia do tego, że proste #create jest 2 razy szybsze. O wiele większe znaczenie z reguły mają selecty ponieważ przeciętnie rzecz biorąc w statystycznej aplikacji wykonywane są kilkaset/kilka tysięcy razy większą ilość razy(przeciętna aplikacja webowa gdzie read jest o wiele częstszy niż create/update)[/quote]
,

Tak, przecietnie rzecz biorac z reguly to tak, faktycznie, ogolnie mowiac prawde piszesz :smiley: A jak trafisz na sytuacje gdzie zrobienie kilkunastu tysiecy insertow morduje serwer to zmienisz zdanie.

To jest tymczasowe, w komentarzu do tego bencha jest napisane, ze sytuacja sie zmieni jak skoncza refactor.

Abstrahując już od aplikacji railsowych, gdzie oczywiście masz rację (renderowanie/parsowanie szablonów też zajmuje kupę czasu), to jednak czasem boli przeczołganie profilerem jakiegoś skryptu korzystającego z AR (z reguły tych samych modeli co nasza aplikacja railsowa - mówię o skryptach “towarzyszących”). Boli dlatego, że nierzadko okazuje się, że 80% czasu procesora zabiera samo opakowanie danych z bazy w modele AR (find/SELECT).[/quote]
A propos optymalnych zapytan, slyszeliscie o Strategic Eager Loading w DataMapper? A o IdentityMap?

Czyms sie trzeba tlumaczyc przed klientem, nie? :wink:

Do dużych importów szybszy jest po prostu SQL, DM z 2x przyspieszeniem #create nie uratuje serwera którego zamordowałby AR. BTW. tak się akurat składa, że w zeszłym tygodniu robiłem import 2 milionów rekordów z użyciem AR - serwer (o dziwo - przecież korzystałem z AR) niezmordowany przemielił wszystko w pół godziny i przeżył. Chyba muszę poczekać aż wolniejsze serwery zastąpią te obecne szybkie. A “Strategic Eager Loading” to świetny termin, prawie tak dobry jak “Structural Investment Vehicle” , niejeden go kupi :smiley:

@Hosiawak: :smiley:

Tutaj warto nadmienić, że jeśli ktoś chce wykonywać dużo i zarazem prostych operacji na danych bez konieczności interakcji ze światem zewnętrznym, to nawet MySQL ma własny język procedur składowanych (MySPL). Którego szybkości przy operacjach na milionach wierszy w porównaniu z AR (wyciągnięcie wszystkich, przeliczenie, władowanie wyników z powrotem w bazę) nawet nie będę porównywał, bo trzeba być człowiekiem :wink:

Oczywiście jakieś misie tu zaraz wyciągną argument o portability, ale

  1. kiedy ostatnio zmienialiście silnik bazodanowy dla jakiejś aplikacji?
  2. PL-ki są do siebie dość podobne i niewiele czasu zajmie tłumaczenie np. MySPL - > plPgSQL

E, to nie tak - każda baza wymaga tuningu pod konkretną aplikację. Nie wystarczy zmienić drivera w konfigu, puścić rake db:migrate i zapuścić benchmark. W ten sposób sprawdzisz czy na losowej konfiguracji bazy A aplikacja jest szybsza niż na losowej konfiguracji bazy B. I można dojść do zaskakujących wniosków.
Osobiście uważam, że aplikacjie intensywnie korzystające z bazy danych nie mogą być pisane w całkowitym oderwaniu od rodzaju bazy - najlepiej nastawić się na początku na taką, która dobrze się zna, i która potrafi się w razie potrzeby podstroić i zoptymalizować. Ewentualnie taką, od której dobry fachowiec jest pod ręką.[/quote]
Z tym, że każdą bazę trzeba odpowiednio skonfigurować się zgodzę.

Jeżeli chodzi o drugą część, czyli optymalizację pod konkretną bazę danych, to tak jak zawsze: fajnie by było, ale jeżeli nie ma problemu z wydajnością to nie babram się w SQLu, nie ma takiej potrzeby - imho to jest przedwczesna optymalizacja. Jeżeli akcja nie jest znacząco wolniejsza, to nie ma sensu optymalizować.

To co jest tak naprawdę ważne, to frontend. Co z tego, że zejdziesz z 200ms do 50 przy generowaniu contentu? Użytkownik tego prawie nie odczuje, ale jeżeli masz niezoptymalizowany frontend to użytkownik na załadowanie całej strony i tak będzie czekał jedną czy dwie sekundy.

Polecam prezentacje Kempera i Koziarskiego o wydajności.

Tak dla jasności o co mi chodziło - bynajmniej nie o optymalizację w nieodpowiednim momencie, tylko o kryteria wyboru.

Ok :slight_smile:

Czyli właściwie myślimy podobnie, tylko jak zwykle się dyskusja o szczegóły rozbija :stuck_out_tongue:

I tu nie masz racji, sa sytuacje, w ktorych ratuje. Co do uzywania czystego SQL to widze to raczej jako ostatnia deske ratunku.

To nic nie udowadnia, wykonales te operacje raz, udalo sie i koniec.

Heh, to nie swietny termin tylko jeden z ciekawszych ficzerow DM