2009-07-26

Nové ORM 8x rychlejší než Hibernate

Dovoluji si představit Vám nový open source ORM framework pro jazyk Java s názvem UJO-ORM, který je postaven na architektuře UJO objektů. Nové ORM řešení vzniklo ve snaze usnadnit vývoj perzistentní vrstvy, nicméně výkonnostní testy ukazují, že dotazy typu SELECT jsou osmkrát rychlejší ve srovnání s Hibernate. Další zajímavé vlastnosti jsou například kontrola typu parametrů v dotazu, malé paměťové nároky a miminální velikost celého řešení.

Úvodní prezentace je zde:
http://ujoframework.org/prezentace/

Výsledky benchmark testů jsou v následující tabulce, podrobnosti o testování najdete v prezentaci:
AkceUJO-ORM Hibernate
META-DATA0.2821.562
INSERT10.14011.407
SELECT22.016175.234
DELETE64.625206.813

ORM home page:
http://ujoframework.org/orm/

Odkaz na zdrojový kód testů je zde:
https://sourceforge.net/projects/ujoframework/files/

Oficiální představení ORM modulu je plánováno na září 2009, nicméně už teď uvítám všechny Vaše podněty a připomínky. V případě zájmu o spolupráci kontaktujte autora na adrese: ujoframework(zavináč)gmail.com .


Pavel

20 komentářů:

Anonymní řekl(a)...

Toto bude urcite dalsi velmi objektivny test pri pouziti komplexneho datoveho modelu, ktory plne vyuziva vsetky moznosti oboch frameworkov.
Prosim vas nedajte sa vysmiat, ale benchmark pri praci s jednou tabulkou je fakt k smiechu.
Skuste pripravit nieco co by sa aspon zdaleka podobalo nejakej netrivialnej aplikacii a pripravte seriozne testy - uz sa tesim na vysledky a uz vidim ako bude ujo-orm za 3-4 roky hlavnym orm riesenim v Java svete.

Ponec řekl(a)...

Jen pro přesnost: bechmark je postaven nad třemi tabulkami. Test se dá určitě zkomplikovat ale já tvrdím, že se tímto výsledky zásadně neovlivní ;)

Anonymní řekl(a)...

Tak to som rad, ze budeme vsetci za par rokov pouzivat len ujo-orm, kedze taketo vykonnostne rozdiely budu urcite kazdeho velmi zaujimat - na vasom mieste v tom pripade napisem o ujo na theserverside, javalobby a pod, nech sa vsetci dozvedia o tomto zazraku

martiner řekl(a)...

Díval jsem se na zdrojáky "benchmarku" pro Hibernate pro select a jsou dvě možnosti: buď Hibernate vůbec neumíte používat, nebo jste to naprogramoval tak blbě úmyslně, aby vám vyšel tak impresivní výsledek. Nevím, co je horší varianta...

Ponec řekl(a)...

> Díval jsem se na zdrojáky "benchmarku"
díky

> Hibernate vůbec neumíte používat To samozřejme nelze vyloučit. Pokud máte námět na zlepšení performance Hibernate, pošlete mi upravený projekt, rád výsledek zveřejním a výsledky aktualizuji.

martiner řekl(a)...

- součástí není definice databázového schématu, tj. není jasné jak a zda se používají indexy
- součástí nejsou data, tj. není jasné, jaké jsou kardinality dat
- v dotazech se nepoužívá join nebo snad dokonce batch fetch

Pokud to naprogramujete tak, že uděláte select z první tabulky, výsledky iterujete v cyklu a pro každý výsledek vyvoláte select z druhé tabulky a select z třetí tabulky a tím opět iterujete, tak to prostě nemůže být rychlé. Ale důvodem není Hibernate, nýbrž to, že je to blbě naprogramované!

Kdybyste řekl, že váš framework je oproti Hibernate rychlejší o 10 nebo 20%, tak řeknu hm a víc se tím nezabývám. Hibernate má oproti JDBC několika procentní režii (bohatě to vyvažuje svými dalšími vlastnostmi). Pokud ale začnete krmit řečmi o 800%, tak v tom na první pohled něco smrdí.

Ponec řekl(a)...

> součástí není definice databázového schématu

databázové schema se zakládá při spuštění testu, relace jsou dány anotacemi BO,
data si test naplní sám

> není jasné jak a zda se používají indexy

ruční přidání indexů bylo na mých testech nevýznamné

> v dotazech se nepoužívá join

V řadě případů se HQL dotaz sestavuje dynamicky a proto ani není možné ho optimalizovat pomocí JOIN.
Nicméně JOIN podporuje i ORM-UJO.

> ... tak v tom na první pohled něco smrdí

to máte pravdu ten velký nepoměr je opravdu zarážející, já však neznám nikoho, komu by se podařilo test Hibernate zrychlit.
Budu proto rád za relevantní oponenturu.

Unknown řekl(a)...

K porovnaniu rychlosti sa vyjadrovat nebudem, ale k samotnej architekture ujo mam niekolko poznamok: je lightweight co je plus, je "deterministicky" teda programator ma plnu kontrolu co je tiez plus, ale je trosku neforemny. Napr. tie queries su kostrbate, zle citatelne, nepaci sa mi to. Taktiez mi nie je jasne ci framework riesi spravu tranzakcii. Zatial som sa na to blizsie nepozrel, ale rozmyslam nad tym.

S pozdravom Tomas Studva

martiner řekl(a)...

"V řadě případů se HQL dotaz sestavuje dynamicky" -- to jsou s prominutím bláboly.

"já však neznám nikoho, komu by se podařilo test Hibernate zrychlit." -- takže jste tím benchmarkem dokázal, že neznáte ani Hibernate, ani nikoho, kdo by alespoň přečetl dokumentaci k Hibernate. Smutné, že?

"Budu proto rád za relevantní oponenturu." -- Aha. to věřím, že byste byl rád. Nicméně co z toho budu mít já? Omluvíte se aspoň za svá tvrzení tam, kde jste tenhle článek zveřejnil?

martiner řekl(a)...

Vynašel jsem si čas se blíže podívat na zdrojáky "benchmarku" pro Hibernate.

Předpokládám, že úkolem je vypsat všechny nesmazané objednávky, uživatele, který přísluší k dané objednávce a všechny nesmazané položky objednávky. Objednávek je celkem 2000, každá má 7 položek.

Původní řešení na mém počítači se vzdálenou PostgreSQL trvalo cca 201s a vyznačovalo se použitím celkem 4 tisíc dotazů - uvnitř cyklu se 2.000 iterací se pokaždé provedly další dva dotazy (proto bylo pomalé).

To je samozřejmě úplně špatně. Jedno z správných řešení zahrnuje naformulování HQL dotazu jako je tento:
select i from PrfOrderItem as i left join fetch i.order as o where i.deleted = :deleted and o.deleted = :odeleted

Ten se přeloží do jednoho selectu, který spojí tabulky objednávek a položek a do dvou dalších selectů, které vytáhnou uživatele -- tj. celkem 3 dotazů.

To trvá na mém počítači 4-6 sekund, tedy hibernate je nejméně 2x rychlejší než váš "framework"!

Unknown řekl(a)...

No neviem ci mate pan martiner pravdu. Ak som spravne pochopil, tak autor sa snazil vykonat vela dotazov v oboch frameworkoch a cas potom porovnat. Vy ste spravil optimalizaciu na urovni dotazov, teda ste vylepsil algoritmus.

Osobne si ale aj tak myslim, ze test je trochu neprehladny a nejasny. Preco nespravit jednoduchy test, vykonat select nad jedinou tabulkou co ja viem vo for-cykle 2000 krat? (musi sa to spravit prave vela krat, lebo pamat, gc, windows, etc.)

Ponec řekl(a)...

> Vynašel jsem si čas se blíže podívat na zdrojáky "benchmarku"

Děkuji.

> ... tedy hibernate je nejméně 2x rychlejší než váš "framework"

To je trochu srovnání hrušek s jablky. Pokud v UJO-ORM použiji JOIN, tak čas SELECTu se zkrátí jedenáctkrát. Poměr obou časů to ovšem změní.

> ... To je samozřejmě úplně špatně

Základní otázka ale zní: jak má vypadat ten "správný" benchmarkový kód? Pokud nás bude zajímat chování serverové aplikace, tak se bude jednat spíše o více kratších SQL dotazů. Výběr vhodného testu by se dal určitě dlouho diskutovat, výsledkem testu však bude vždy jen přibližný obraz reálného provozu.

Existuje i jiný pohled na věc: aplikační programátor pod časovým tlakem použije raději odladěné služby vracející kolekci BO a tak raději pospojuje hotové řešení za cenu určitého zpomalení kódu.

Ponec řekl(a)...

Tomáši,
přikládám několik poznámek:

> Napr. tie queries su kostrbate, zle citatelne, nepaci sa mi to.

Rozumím, ale s tím bohužel nebude možné jednoduše nic dělat. Výhodou může být snad sestavení výsledné Criterion z předpřipravených částí či typová kontrola použitých parametrů dotazu.

> Taktiez mi nie je jasne ci framework riesi spravu tranzakcii.

Zjednodušeně: metody session.commit/rollback provolávají přímo DB connection a tak s transakcemi je to podobné jako v JDBC. Pokud potřebujete další transakci, otevřete si další UJO Session.

Peto řekl(a)...

Zdravim, ujo je fajn experiment... Dalo by sa povedat ze je to taka mila mala "slovna hracka v jazyku java". Je postaveny na zaujimavom napade, ALE... nemyslim si ze je akokolvek pouzitelny v realnych enterprise aplikaciach (a pravdepodobne nikdy nebude), preto je porovnanie s hibernate (ktory mimochodom tym enterprise aplikaciam prave teraz kraluje) absolute nepodstatne!!!
Aj keby bol ujo 20x rychlejsi ako hibernate tak to nic nezmeni!!! Rychlost nie je jediny parameter ktory je totizto podstatny.

Ad. realnost testu: myslim si ze je to vcelku uveritelne ze je ujo niekolko x rychlejsi, ked si porovnate tie sposoby citania properties: reflection vs. map.
Bohuzial realne app. bezne nerobia iba hrcu selektov (alebo aspon nie tie, ktore pouzivaju orm). A v realnej aplikacii by tu rychlostnu vyhodu velmi skoro zakryli problemy s designom aplikacie, ktory je pri pouziti ujo nepochybne dost chlpaty.
Vid. Effective Java: Item 55 ;)

Ako som pisal, ujo je zaujimava vec (a jWorkSheet aj osobne pouzivam :) ale na poli enterprise javy asi nikdy nebude znamenat vela... A porovnania s fw. ako hibernate s nadpismi za ktore by sa ani bulvar nehanbil na tom nic nezmenia, skor naopak...

Kamilos řekl(a)...

Zdravím. Oceňuji vaší snahu a nechápu všechny kritiky zde. Asi není moc šťastné začínající projekt hned srovnávat s hibernate. Ale vážím si každého, kdo se pokusí o něco inovativního a zabývá se nečím zajímavým. Dobrá práce!

Ponec řekl(a)...

Peto, děkuji za názor

> designom ... pri pouziti ujo nepochybne dost chlpaty

můžete být více konkrétní, prosím?

Peto řekl(a)...

Ad chlpaty design:
1/ Getre z jworksheetu typu WorkDay.P_EVENTS.getList(workDay) mi pripadaju extremne zle citatelne. Viem, da sa to zabalit do normalnych getrov, ale tie mi uz eclipse nevygeneruje a musim si ich pisat sam... a ja som lenivy :)
2/ Kazdy objekt musi implementovat interface Ujo. A to je dost invazivne, hlavna vyhoda hibernatu spociva v tom ze dokaze pouzivat POJO a tie su imho o dost pohodlnejsie a prehladnejsie ako UJO...

ps: Hibernate poskytuje moznost implementovat si vlastny Tuplizer, co je trieda manazujuca vytvaranie / citanie / naplnanie entit, ak si spravite vlastnu, ktora nebude pouzivat reflexiu tak by sa rozdiely medzi Ujo a Hibernatom asi zmensili... aj ked... hibernate je dost biedne napisana kniznica a jej autori zjavne nepochopili princip patternu strategie a tak niektore tieto ich interface zvycajne nefunguju tak ako by si clovek predstavoval...

Ponec řekl(a)...

> Getre z jworksheetu typu WorkDay.P_EVENTS.getList(workDay) mi pripadaju extremne zle citatelne

Ok, jWorkSheet vznikal na jádře UJO 0.7. V současné verzi je dostupná i čitelnější alternativa:
workDay.get(WorkDay.P_EVENTS)

> ... vlastny Tuplizer

můžu prozradit, že toto téma je připravené na nějaký příští blog :)

Ladicek řekl(a)...

EVENTS.getList(workDay) je z určitého úhlu pohledu mnohem lepší než workDay.getEvents(). Takové ListAttrib.getList(workDay, P_EVENTS), to je teprv zrůda :-)

Ponec řekl(a)...

Na základě vašich připomínek jsem srovnávací testy doplnil, výsledky jsou zde: http://ujoframework-cs.blogspot.com/2009/08/ujo-orm-doplnene-testy.html