Closed DocX closed 7 years ago
@DocX thanks a bunch! I have tried doing something like this a couple of times and fallen short, so much so that I had been just suggesting not using the attributes macro unless you really need it.
I am going to take a bit of time and study this, but I will likely merge this weekend.
In our application we use
JaSerializer.PhoenixView
and we noticed rather poor performance when rendering lot of data with big models.I did some
mix profiler.fprof
tracing and noticed there is lot of function calls caused by that each attribute in the serializer module genrated by DSL is a method call, which is even called twice to translate from/2
to/1
signature.Even tho in the end it is all simple
Map.get
operations, the pure fact of invoking method calls have some overhead in Elixir's (resp. Erlang's) VM.Here is a patch that using Elixir's macros generate attributes map compile time. On top of that I modified attributes macro to avoid
apply
and hence to make use of@compile {:inline}
to inline each of the attribute methods during compile time as well. The result is that call toattributes
doesn't have descendant method calls and instead the whole map construction is inlined.I also added benchmark for those, here are results (MacBook Pro 2.7 GHz Intel Core i5):
master (b5d9f1d)
:inline-dsl-attributes
:As you can see there is definitive boost in the
attributes
function. The overall render is not much better, but it is still better.There is definitely more room to go - inline other serialized fields like meta, id, ... - And perhaps then inline the whole data map for given object. Not sure how far this can be stretched before it is "needed" to go runtime.
Let me know what you think.