tools.cli/parse-opts
接受参数列表,选项规范和附加选项。它调用 compile-option-specs
和 required-arguments
生成 specs
和 req
。然后,它使用这些规格和要求对提供的参数进行检查(包括选项)。对于特定应用程序,前两个步骤调用之间不会变化。
我提出一个新的 make-parse-opts-fn
函数,该函数前置执行 compile-option-specs
和 required-arguments
并返回一个依赖于编译后的 specs
和 req
的函数。它可以这样使用:(def compiled-parser (make-parse-opts-fn cli-options))
。
使用criterion进行的微基准测试显示,速度提高了不止两倍(首先是 tools.cli/parse-opts,其次是预编译解析器)
; user=> (def cli-options
[["-h" "--help" "This message"]
[nil "--extra" "Output in extra format"
:default false]
["-q" "--quiet" "Print no suggestions, only return exit code"
:default false]])
#'user/cli-options
; user=> (bench (cli/parse-opts ["--quiet" "src"] 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=> (bench (compiled-parser ["--quiet" "src"] :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
如果将附加选项也提升到 make-parse-opts-fn
中(以牺牲灵活性为代价提高速度),差异会更显著,相对于现有的 tools.cli/parse-opts
函数,速度提高了大约10倍
; user=> (bench (compiled-parser-2 ["--quiet" "src"]))
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
如果有兴趣,我可以提供补丁。