Blog | Pozor na výkon kompozice funkcí a partial application v Clojure

Pozor na výkon kompozice funkcí a partial application v Clojure

Jen tak na test jsem si zkusil zjistit, jak ovlivní rychlost použití kompozice funkcí a partial application. Vliv na výkon mě velmi (negativně) překvapil. Příště budu muset víc testovat své funkce, jaký vliv má kompozice funkcí a partial application na výkon.

Mějme funkcí, která k parametru přičte dvojku. Tuto funkci jsem naprogramoval třemi způsoby:

(defn plus-2-1 [n] (+ 2 n)) ; stary a nudny zpusob
(def plus-2-2 (partial + 2)) ; partial application
(def plus-2-3 (comp inc inc)) ; kompozice funkci

Pak si zjistím čas, který to trvalo:

(time (dotimes [n 10000000] (plus-2-1 n)))
"Elapsed time: 167.281 msecs"
nil

(time (dotimes [n 10000000] (plus-2-2 n)))
"Elapsed time: 2792.596 msecs"
nil

(time (dotimes [n 10000000] (plus-2-3 n)))
"Elapsed time: 474.593 msecs"
nil

Jak je vidět, kompozice funkcí trvá asi 2-3 delší dobu (to bude tím, že skládám dvě funkce + 1 a proto se provedou dva součty místo přímo přičtení 2 plus nějaká - nemalá - režie).

Když si totiž definuju funkci:

(defn plus-2-4 [n] (inc (inc n)))
(time (dotimes [n 10000000] (plus-2-4 n)))
"Elapsed time: 268.591 msecs"
nil

Vidím, že čas je oproti plus-2-3 pořád výrazně lepší.

Proč je ale partial application 16* pomalejší, tomu nerozumím.

Každopádně takováto forma optimalizace se hodí jen tam, kde se funkce volá opravdu hodně. Režie nejpomalejší funkce (partial application) oproti nejrychlejší (+ 2 n) je na mém počítači 262 nanosekund, to je 2,62e-7 sekund (čas, za který světlo urazí asi 78 metrů, asi miliontina času mrknutí, tedy opravdu krátký čas).

Nepomohlo ani statické typování, funkce:

(defn plus-2-5 [^Integer n] (+ 2 n))

Je zhruba stejně výkonná jako dynamicky typovaná funkce plus-2-1.

Pro zajímavost, PHP toto trvá 3,02 vteřiny a je pomalejší, než nejpomalejší řešení a oproti nejlepšímu zaostává dokonce 18*. Naopak node.js osciluje kolem 20 milisekund, je 8* rychlejší, než řešení v Clojure (v REPLu, zkompilovaný program by byl nejspíš srovnatelný) a 150* rychlejší, než PHP.

Programování

Předejte zkušenosti i dalším a sdílejte tento článek!



Jiří Knesl
Business & IT konzultant

Jiří Knesl poprvé začal programovat v roce 1993. Od té doby, díky skvělým učitelům a později zákazníkům, měl možnost neustále růst v oboru vývoje webových aplikací a informačních systémů. v roce 2002 se přidal zájem o ekonomii a v roce 2006 o organizaci práce. Vším tím se konstantně profesně zabývá jak ve svém podnikání, tak i u zákazníků. Za posledních 5 let vydal na tato témata přes 400 článků.

Prohlédněte si moje reference

Mám zkušenosti z rozsáhlých projektů pro korporace, velké podniky, střední i malé firmy, ale i pro startupy v cloudu. Zvyšoval jsem jejich know-how, pomáhal nastavovat jejich organizační strukturu, byl lektorem a mentorem v náročných situacích. Podívejte se, jak vidí můj přínos samotní klienti.

Sledujte mé postřehy na sociálních sítích