<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged reuqest</title>
<link>https://ask.clojure.org/index.php/tag/reuqest</link>
<description></description>
<item>
<title>Compile parser ahead of time</title>
<link>https://ask.clojure.org/index.php/12697/compile-parser-ahead-of-time</link>
<description>&lt;p&gt;&lt;code&gt;tools.cli/parse-opts&lt;/code&gt; accepts the args, the option-spec, and the additional options. It calls &lt;code&gt;compile-option-specs&lt;/code&gt; and &lt;code&gt;required-arguments&lt;/code&gt; to build the &lt;code&gt;specs&lt;/code&gt; and &lt;code&gt;req&lt;/code&gt;. Then it performs the validation with those specs and req on the provided &lt;code&gt;args&lt;/code&gt; (along with the options). For a given application, the first two steps aren't going to change across calls.&lt;/p&gt;
&lt;p&gt;I propose a new &lt;code&gt;make-parse-opts-fn&lt;/code&gt; function that performs the &lt;code&gt;compile-option-specs&lt;/code&gt; and &lt;code&gt;required-arguments&lt;/code&gt; up front and returns a function that relies on the compiled &lt;code&gt;specs&lt;/code&gt; and &lt;code&gt;req&lt;/code&gt;. It could be used like this: &lt;code&gt;(def compiled-parser (make-parse-opts-fn cli-options))&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Microbenchmarking with criterium shows a more than double increase in speed (tools.cli/parse-opts first, pre-compiled parser second):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;; user=&amp;gt; (def cli-options
  [[&quot;-h&quot; &quot;--help&quot; &quot;This message&quot;]
   [nil &quot;--extra&quot; &quot;Output in extra format&quot;
    :default false]
   [&quot;-q&quot; &quot;--quiet&quot; &quot;Print no suggestions, only return exit code&quot;
    :default false]])
#'user/cli-options

; user=&amp;gt; (bench (cli/parse-opts [&quot;--quiet&quot; &quot;src&quot;] cli-options :in-order true))
Evaluation count : 10962 in 6 samples of 1827 calls.
             Execution time mean : 65.021329 µs
    Execution time std-deviation : 5.276033 µs
   Execution time lower quantile : 58.658638 µs ( 2.5%)
   Execution time upper quantile : 69.724228 µs (97.5%)
                   Overhead used : 9.607933 ns
nil

; user=&amp;gt; (bench (compiled-parser [&quot;--quiet&quot; &quot;src&quot;] :in-order true))
Evaluation count : 24660 in 6 samples of 4110 calls.
             Execution time mean : 25.090846 µs
    Execution time std-deviation : 253.361821 ns
   Execution time lower quantile : 24.769079 µs ( 2.5%)
   Execution time upper quantile : 25.413286 µs (97.5%)
                   Overhead used : 9.607933 ns
nil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the additional options are lifted into the &lt;code&gt;make-parse-opts-fn&lt;/code&gt; as well (trading flexibility for speed), the difference is even more dramatic, providing roughly 10x speed increase over the existing &lt;code&gt;tools.cli/parse-opts&lt;/code&gt; function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;; user=&amp;gt; (bench (compiled-parser-2 [&quot;--quiet&quot; &quot;src&quot;]))
Evaluation count : 73116 in 6 samples of 12186 calls.
             Execution time mean : 8.349923 µs
    Execution time std-deviation : 51.419864 ns
   Execution time lower quantile : 8.282266 µs ( 2.5%)
   Execution time upper quantile : 8.407998 µs (97.5%)
                   Overhead used : 9.607933 ns

Found 2 outliers in 6 samples (33.3333 %)
	low-severe	 1 (16.6667 %)
	low-mild	 1 (16.6667 %)
 Variance from outliers : 13.8889 % Variance is moderately inflated by outliers
nil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I can provide a patch for this if there's interest.&lt;/p&gt;
</description>
<category>tools.cli</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12697/compile-parser-ahead-of-time</guid>
<pubDate>Mon, 27 Feb 2023 19:57:36 +0000</pubDate>
</item>
</channel>
</rss>