metosin / reitit

A fast data-driven routing library for Clojure/Script

Home Page:https://cljdoc.org/d/metosin/reitit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Optimizing interceptors with function composition

grmble opened this issue · comments

Effectless interceptors and handlers could be composed, reducing the number of steps for the executor and helping with thread pool overhead for async code.

I made a proof of concept here: https://github.com/grmble/interceptor-optimizer

For detailed explanations see the linked README, but the gist is

  • interceptors and handlers can opt into optimization by declaring themselves :composable via metadata - no async results, no changing the flow of control (queue manipulations or catching exceptions)
  • the optimizer finds all runs of consecutive composables and composes them

A benchmark for a simple sync example (1 :error, 1 :enter, 1 :leave, 1 handler) gives a 14% improvement. That being said, I care more about composing :leave blocks that come after async code, but that is harder to measure.

It is not througly tested - I only ever ran the one same example, and I only ever used the sieppari executor, but I do think that the approach shows promise.

The benchmark numbers are from https://github.com/grmble/interceptor-optimizer/blob/master/src/grmble/interceptor_optimizer/dev.clj#L39-L58

Edit: updated line numbers