weavejester/ataraxy

Method code too large!

Opened this issue · 3 comments

Hi. I was testing different routing libs and noticed that ataraxy fails on large routing trees:

(require '[ataraxy.core :as ataraxy])

(def aroutes
  (ataraxy/compile
    (->> (range 100)
         (map (partial str "command"))
         (mapv (fn [command] [(str "/api/" command) [(keyword command)]]))
         (into {}))))

(ataraxy/matches aroutes {:uri "/api/command55"})
; [:command55]

(ataraxy/compile
  (->> (range 200)
       (map (partial str "command"))
       (mapv (fn [command] [(str "/api/" command) [(keyword command)]]))
       (into {})))
; CompilerException java.lang.RuntimeException: Method code too large!

tested with 0.4.0.

Thanks for the report. It looks like I'll need to consider ways of reducing the code generated, or splitting the route up into multiple methods.

I think the problem stems from how compile-match-route is (recursively) expanded, producing more and more expressions (via the compile-match-result, compile-match-destruct etc etc calls). All of these nested expressions end up being part of the same function (the one returned by compile-match).

Without having tried it, I believe the whole thing can be avoided by returning no-arg fns, as opposed to expressions, from all the following, and doing a linear search via some-fn (or something along these lines). I doubt it would hurt performance...

  • compile-match-result
  • compile-match-destruct
  • compile-match-params
  • compile-match-method
  • compile-match-path

This way the recursive macro expansion would produce more and more fn invocations, rather than more and more raw code.

I can have a crack at this maybe this weekend or the next, if you're interested.

Ok, I just had a quick stab at this and it's not as straight-forward as I thought. :(