Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision Next revision Both sides next revision | ||
treex:api-implementation [2015/12/08 17:52] popel created |
treex:api-implementation [2015/12/11 12:29] popel |
||
---|---|---|---|
Line 10: | Line 10: | ||
Přijde mi tedy výhodnější ukládat rovnou referenci na daný uzel (než int, který by se musel měnit, pokud bych přidal uzly na začátek věty). | Přijde mi tedy výhodnější ukládat rovnou referenci na daný uzel (než int, který by se musel měnit, pokud bych přidal uzly na začátek věty). | ||
+ | === Sdílení klíčů === | ||
+ | |||
+ | V Perlu a Pythonu jsou objekty implementovány jako hash table. Má-li třída Node atributy form, lemma,... a chceme milion uzlů, bylo by vhodné neukládat řetězce " | ||
+ | |||
+ | === Sdílení hodnot === | ||
+ | |||
+ | Mnoho uzlů má stejné lemma, formu, formém, tag atd. | ||
+ | Mohl bych tedy vytvořit slovník těchto stringů (mapující string na integerové idéčko a naopak) a do instancí uzlů ukládat místo stringů jen ta idéčka. | ||
+ | |||
+ | V Perlu zabírá string (o 0-15 jednobajtových znacích) 56 bajtů, ale když dám stringy do pole, tak se to zaokrouhlí na 64 bajtů. | ||
+ | Int zabírá 24 bajtů a v poli 32 bajtů. | ||
+ | Když dám stringy/ | ||
+ | |||
+ | perl -MDevel:: | ||
+ | perl -MDevel:: | ||
+ | perl -MDevel:: | ||
+ | |||
+ | Reference v Perlu zabírá stejně jako int (a to těch 24 bajtů samostatně, | ||
+ | (V Céčku na 64bitech má typicky pointer 8 bajtů, int 4 bajty a long long int 8 bajtů, v poli to zůstává stejné, v hashi přibude režie dle míry naplnění tabulky, ale v Céčku se objekty nedávají do hashe, leda snad wild atributy.) | ||
+ | Z hlediska rychlosti by bylo lepší ukládat přímo referenci na string (místo intu, kterým by se pak muselo indexovat pole). | ||
+ | Ušetřil bych 32 bajtů na každém stringovém atributu (a pokud by měl ten string víc než 15 znaků, tak ještě víc) a navíc bych potřeboval paměť pro slovník, která je ale (díky zipfovskému rozdělení lemmat, na větších dokumentech) zanedbatelná. | ||
+ | Mám-li v uzlu 4 stringové atributy (form, | ||
+ | |||
+ | Samozřejmě by bylo mnohem úspornější tyto datové struktury implementovat v Céčku a jen udělat binding pro Perl a Python. | ||
+ | |||
+ | Je dobré testovat i celkovou paměť virtuální i resident: | ||
+ | |||
+ | perl -MDevel:: | ||
+ | 96277560 | ||
+ | VSZ | ||
+ | 292780 271456 270416 | ||
+ | |||
+ | Zde je vidět, že Devel:: | ||
+ | |||
+ | ==== Benchmark Perlích accessorů ==== | ||
+ | Zápis následovaný čtením atributu | ||
+ | LV V::Magic H 64 759/s | ||
+ | LV V::Magic A 74 649/s | ||
+ | LV Sentinel H 169 605/s | ||
+ | LV Sentinel A 170 267/s | ||
+ | Moose 1 155 163/s | ||
+ | object H 1 193 837/s | ||
+ | object A 1 233 004/s | ||
+ | LV C:: | ||
+ | Mouse 3 111 529/s | ||
+ | LV C:: | ||
+ | C:: | ||
+ | Moops 3 688 969/s | ||
+ | Moo 3 738 065/s | ||
+ | O:: | ||
+ | C:: | ||
+ | hash 4 969 215/s | ||
+ | array 5 386 997/s | ||
+ | |||
+ | Zápis atributu | ||
+ | H-lv-check-sentinel | ||
+ | A-lv-check-sentinel | ||
+ | A-set-check-perl | ||
+ | H-set-check-perl | ||
+ | --- | ||
+ | H-set-lemma-perl | ||
+ | A-set-lemma-perl | ||
+ | A-lv-lemma-perl | ||
+ | H-lv-lemma-perl | ||
+ | --- | ||
+ | A-set-lemma-xs | ||
+ | H-set-lemma-xs | ||
+ | H-lv-lemma-xs | ||
+ | A-lv-lemma-xs | ||
+ | --- | ||
+ | H-direct | ||
+ | A-direct | ||
+ | |||
+ | Čtení atributu: | ||
+ | h-lv_check_sentinel | ||
+ | a-lv_check_sentinel | ||
+ | --- | ||
+ | h-get_lemma_perl | ||
+ | a-get_lemma_perl | ||
+ | h-lv_lemma_perl | ||
+ | a-lv_lemma_perl | ||
+ | --- | ||
+ | h-lv_lemma_xs | ||
+ | a-lv_lemma_xs | ||
+ | h-get_lemma_xs | ||
+ | a-get_lemma_xs | ||
+ | --- | ||
+ | h-direct | ||
+ | a-direct | ||
+ | |||
+ | Co z toho plyne? | ||
+ | * Všechny čtení i zápisy přístupy jsou zřejmě " | ||
+ | * Pole jsou jen o málo rychlejší než hashe. Možná by se rozdíl zvětšil, kdybych měl v objektu více atributů než jeden, ale víc než 16 jich asi mít nechceme ('' | ||
+ | * Čtení je podobně rychlé jako zápis atributu obdobnou metodou. | ||
+ | * Nejrychlejší je přímý přístup do hashe/pole (tedy '' | ||
+ | * XS implementace jsou asi dvakrát rychlejší než perlové (a to v těch perlových dělám, '' | ||
+ | * Největší otázka z hlediska API je, zda povolit **lvalue accessory**, | ||
+ | * Obzvlášť užitečné je použití typu '' | ||
+ | * V Perlu to není moc zvykem (byť to byla jedna z hlavních motivací uživatelských lvalue funkcí). | ||
+ | * Dokud při zápisu nechci dělat nic jiného (kontroly, logování, | ||
+ | * Jakmile chci nějakou kontrolu v setteru (třeba že ord je kladný integer nebo deprel je jen z těch povolených), | ||
+ | * Pokud chci dělat kontroly (či logování atd.) u lvalue accessoru, musím použít (něco jako) [[https:// | ||
+ | * Hlavní problém vidím v tom, že se mi pak zpomaluje i čtení atributu, při jehož zápisu je lvalue-check. Celé to dělám proto, aby se to " | ||
+ | * Když bych tedy v Perlu používal lvalue accessory, tak jakmile se rozhodnu přidat nějakou kontrolu/ | ||
+ | * Přidáním kontroly/ | ||
+ | * To 3x zpomalení při zápisu by mi nevadilo. Ale to 5x násobné zpomalení při čtení je nepříjemné, |