Dave Kleinschmidt
Dave Kleinschmidt
It does seem to only happen in global/REPL scope: ```julia julia> g() = @formula(y ~ log(x) + log(y) + log(z)) g (generic function with 1 method) julia> @time g() 0.366315...
yeah so maybe that (and `@btime`) is just estimating the time to actually run the constructors that are returned?
it's also not the macro itself: ```julia julia> @time @macroexpand @formula(y ~ log(x) + log(y)) 0.000954 seconds (301 allocations: 17.516 KiB) :(StatsModels.Term(:y) ~ StatsModels.capture_call(log, ((x,)->log(x)), (:x,), $(Expr(:copyast, :($(QuoteNode(:(log(x))))))), [StatsModels.Term(:x)]) +...
and it's not (entirely) the `capture_call`: ```julia julia> @time StatsModels.capture_call(log, x->log(x), (:x, ), :(log(x)), [StatsModels.Term(:x)]) 0.011115 seconds (7.08 k allocations: 380.571 KiB) (x)->log(x) julia> @time StatsModels.capture_call(log, x->log(x), (:x, ), :(log(x)),...
So this COULD all be compiler time, because running the same *macro* twice in global scope gives different types for the anonymous functions, but calling twice a function that wraps...
This is making me more and more convinced that @oxinabox proposal (in #117 I think) to do away with the anonymous function version of the `FunctionTerm` and just use the...
I've now implemented that suggestion (#183), which doesn't create a new anonymous function but just stores the head function and the args. With that PR we get the expected behavior,...
Sprinkling `@nospecialize` doesn't really seem to help, so I also got rid of the tuple-based representation of concatenated terms in favor of `Vector{AbstractTerm}` (where the type is the same no...
In order to be a bit more systematic about this, I created a very dumb benchmarking script which just runs a bunch of formula expressions twice and prints the timings....
We've run into a very similar use case recently, wanting to generate table-like things from the outputs of simulations where there's one entry in a vector per coef, and want...