[ Skip to the content ]

Institute of Formal and Applied Linguistics Wiki


[ Back to the navigation ]

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
treex:api-implementation [2016/01/08 18:28]
popel
treex:api-implementation [2016/01/08 23:17] (current)
popel
Line 172: Line 172:
  
  
-===== Benchmark načítání CoNLL-U v Perlu =====+===== Profiling načítání CoNLL-U v Perlu =====
 Načítám cs-ud-train-l.conllu (68 MB, 41k sentences, 0.8 MWords). Časy v sekundách. Excl(usive) časy se sčítají, krom těch označených "x", což jsou pomocné (alternativní) experimenty. Načítám cs-ud-train-l.conllu (68 MB, 41k sentences, 0.8 MWords). Časy v sekundách. Excl(usive) časy se sčítají, krom těch označených "x", což jsou pomocné (alternativní) experimenty.
  
Line 178: Line 178:
 | 0.5 | 0.5 | ''while (<$fh>) {chomp;}''             | načtení řádka po řádce | | 0.5 | 0.5 | ''while (<$fh>) {chomp;}''             | načtení řádka po řádce |
 | 0.3 | 0.8 | ''$line eq "" or $line =~ /^#/''       | test prázdné řádky a komentáře | | 0.3 | 0.8 | ''$line eq "" or $line =~ /^#/''       | test prázdné řádky a komentáře |
-| 0.| 1.| ''split /\t/, $line''                  | split 9 atributů dle tabů | +| 0.| 1.| ''split /\t/, $line''                  | split 9 atributů dle tabů (výsledek se zahodí) 
-| 4.| 5.| ''my ($id, $form, $lemma,...) =''      | uložení těch hodnot do proměnných | +| 4.| 5.| ''($id, $form, $lemma,...) =...''      | uložení těch hodnot do proměnných 
-|x3.9 |     | ''UD::Node->new(form=>$form,...)''     | vytvoření 0.8M uzlů se stejnými atributy| +|x5.6 | 7.0 | ''my ($id, $form, $lemma,...) =...''   | uložení těch hodnot do nově alokovaných proměnných (které se asi odalokují, až vypadnou ze scope) | 
-| 4.|10.3 | ''UD::Node->new(form=>$form,...)''     | vytvoření 0.8M uzlů ze skutečných dat|+|x4.7 | 6.1 | ''@pole =...''                         | uložení těch hodnot do pole 
 +|x3.9 |     | ''UD::Node->new(form=>$form,...)''     | vytvoření 0.8M uzlů se stejnými atributy, tedy 200K uzlů za sekundu, viz [[#Benchmark konstruktorů v Perlu|následující benchmark]]
 +| 4.|10.3 | ''UD::Node->new(form=>$form,...)''     | vytvoření 0.8M uzlů ze skutečných dat|
 |x0.4 |10.7 | ''push @all_nodes, $node''             | uzly se ukládají do pole| |x0.4 |10.7 | ''push @all_nodes, $node''             | uzly se ukládají do pole|
 | 1.9 |12.2 | ''weaken($node->{_parent}=$root)...''  | uzly se ukládají do dokumentu, věší se na kořen, přidávají do jeho seznamu dětí| | 1.9 |12.2 | ''weaken($node->{_parent}=$root)...''  | uzly se ukládají do dokumentu, věší se na kořen, přidávají do jeho seznamu dětí|
 | 1.2 |13.4 | ''weaken($node->{_parent}=$parent)...''| uzly se věší na skutečného rodiče (v druhém průchodu, pomocné pole ''@parents'')| | 1.2 |13.4 | ''weaken($node->{_parent}=$parent)...''| uzly se věší na skutečného rodiče (v druhém průchodu, pomocné pole ''@parents'')|
-2.|15.| ''set_parent($parent,{cycles=>'no-check'})''set_parent místo optimalizovaného kódu (který neřešil předchozího rodiče atd.)| +1.|14.| ''set_parent_nocheck($parent)''        set_parent_nocheck místo optimalizovaného kódu (který neřešil předchozího rodiče atd.)| 
-0.|**16.6**| ''set_parent($parent)''                | testování cyklů |+1.|**16.6**| ''set_parent($parent)''             | testování cyklů |
 |10.0 |26.6 | ''$root->create_child...''             | původní implementace, kde se uzly převěšují z kořene na skutečného rodiče a děti jsou pole| |10.0 |26.6 | ''$root->create_child...''             | původní implementace, kde se uzly převěšují z kořene na skutečného rodiče a děti jsou pole|
  
  
-  * Původní implementace byla velmi neefektivní, protože se při převěšování z kořene musely uzly odebrat z pole dětí kořene, čili se muselo to pole překopírovat a zmenšit o jeden prvek a složitost byla kvadratická. Samotné převěšení trvalo 7s (a ještě 3s se někde ztratily). Kdyby byly děti implementované spojákem místo pole (to mám stále v plánu), tak to bude rychlejší, ale stejně je zbytečné při načítání CoNLL-U uzly dávat do spojáků dětí kořene, ze kterého vím, že je budu za chvíli odebírat. +  * Původní implementace byla velmi neefektivní, protože se při převěšování z kořene musely uzly odebrat z pole dětí kořene, čili se muselo to pole překopírovat a zmenšit o jeden prvek a složitost byla kvadratická. Samotné převěšení trvalo 7s (a ještě 3s asi kvůli ''$root->create_child(...)'' místo ''UD::Node->new(...)''). Kdyby byly děti implementované spojákem místo pole (to mám stále v plánu), tak to bude míň než 7s, ale stejně je zbytečné při načítání CoNLL-U uzly dávat do spojáků dětí kořene, ze kterého vím, že je budu za chvíli odebírat. 
-  * Ušetřil jsem 10stedy víc než 7sVolám přímo ''UD::Node->new(...)'' místo ''$root->create_child(...)''+  * Vypuštěním testování cyklů v CoNLL-závislostech se ušetří 1.8s, což za to asi nestojí. 
-  * Ještě víc by šlo ušetřit vypuštěním testování cyklů v CoNLL-U závislostech (1sa optimalizací kódu set_parent bez volání této metody (další 2s). +  * Původně jsem používal ''set_parent($parent{cycles=>'no-check'})'', jenže vytváření toho hashe s parametrem spolklo asi polovinu času ušetřeného vypuštěním kontroly cyklů. 
-  * Nyní se nejvíc času stráví samotným vytvářením uzlů (10.917s-0.844s). To musím ještě prozkoumat.+  * Optimalizací kódu set_parent bez volání této metody se ušetří 1.4s. To za to asi taky nestojí. 
 +  * Poměrně dost času (4.1s) zabere naplnění 9 proměnných ''$form, $lemma,...''. Při ''UD::Node->new(form=>$form,...)'' se tyto proměnné kopírují do hashe, který bude instancí objektuCelkem to trvá 4.8s, tedy zřejmě 4.1s kopírování a 0.7s vytvoření hashe a jeho blessování, ale celé je to v XS (asi o 20% rychlejší než v Perlu), takže kdo ví
 +  * Zdá se, že deklarováním 9 'my' proměnných až ve vnitřním cyklu přes uzly/řádky si přidám 1.5s. Možná proto, že se musejí odalokovávat (nebo přepisovat na undef), když vypadnou ze scope. 
 +  * Myslel jsem si, že by místo 9 proměnných mohlo být rychlejší jedno pole, ale to je pomalejší (už jen naplnění toho pole, zatím bez vytváření uzlu), a to o 0.6s. Vlastně se není co divit, protože perlí pole má krom nějakou režii navíc
 +  * Když jsem všechny uzly z celého souboru ukládal do jednoho pole, tak odalokování pole (0.8M uzlůtrvalo cca 1s. To jsem do profilingu nezahrnul, ale benchmark jsem musel ručně spouštět víckrát.
  
 ===== Benchmark konstruktorů v Perlu ===== ===== Benchmark konstruktorů v Perlu =====
Line 208: Line 214:
   XSAccAf  324620 Class::XSAccessor::Array, sub fastnew {my $c=shift; bless [@_], $c;}   XSAccAf  324620 Class::XSAccessor::Array, sub fastnew {my $c=shift; bless [@_], $c;}
   ManualAf 333188 Manual array-based object, sub fastnew {my $c=shift; bless [@_], $c;}   ManualAf 333188 Manual array-based object, sub fastnew {my $c=shift; bless [@_], $c;}
- 
  

[ Back to the navigation ] [ Back to the content ]