Ah, df has no effect on a JIT system, I forgot about that. Is the memory
measurements guaranteed to have consistent effect of the GC across
benchmarks?

On Mon, Jan 3, 2022 at 20:06 Wiebe-Marten Wijnja <w...@resilia.nl> wrote:

> I have run some benchmarks (comparing OTP23 with JIT-enabled OTP24).
> Full results here: https://github.com/Qqwy/elixir-test-benchmrking_then/
>
> It compares, in a situation where no tail recursion optimization is
> possible, `Kernel.then/2` vs. writing the same code manually vs. using
> `Kernel.then/2` with `@compile :inline`.
>
>
> A brief summary of the results:
>
> - OTP24 is able to get roughly twice as many iterations per second as
> OTP23. However:
> - On OTP24:
>   - using `Kernel.then/2` requires (when tail recursion is not possible)
> 2.5x the memory of the other two variants.
>   - using `Kernel.then/2`is roughly 30% slower than the other two variants.
> - On OTP23:
>   - all three techniques use the same amount of memory.
>   - using `Kernel.then/2`is roughly 8% slower than the other two variants.
>
> Strange...
>
>
> I also took a look at the disassembled code using :erts_debug.df as you
> suggested.
> Details here:
> https://github.com/Qqwy/elixir-test-benchmrking_then/#looking-at-the-disassembled-code
> *(Note that under OTP24 the *.dis-files only contained 1-5 empty lines, so
> the output is from OTP23. Should I file a bug with the OTP team for this?)*
>
> It seems that also during loading, no optimization of immediately-called
> anonymous functions is taking place.
> Above benchmarks seem to support this fact, although the results w.r.t.
> memory usage and the difference in slowdown vs OTP23/24 seems very odd to
> me.
>
>
> How to continue?
>
>
> ~Marten/Qqwy
> On 03-01-2022 17:30, José Valim wrote:
>
> The optimization may happen on the loader. Use erts_debug:df(Mod, Fun,
> Arity) and see that.
>
> On Mon, Jan 3, 2022 at 5:03 PM Wiebe-Marten Wijnja <w...@resilia.nl> wrote:
>
>> I've been running my tests on Elixir v1.13.1 built for OTP24 with OTP
>> 24.1.2.
>> When decompiling the resulting BEAM bytecode, the anonymous functions are
>> still visible.
>>
>> I will do some benchmarks to see how the resulting performance is. Maybe
>> the JIT will do something which is not visible in the BEAM bytecode.
>> On 03-01-2022 16:57, José Valim wrote:
>>
>> then/2 is a macro and the emitted code should be optimized from
>> Erlang/OTP 24+.
>>
>> On Mon, Jan 3, 2022 at 4:28 PM w...@resilia.nl <w...@resilia.nl> wrote:
>>
>>> Since v1.12 we have the macro `Kernel.then(value, function)` which
>>> expects an arity-1 function and will call it with the given value.
>>>
>>> This makes code which used to be written as follows:
>>>
>>> ```
>>> def update(params, socket) do
>>>   socket =
>>>     socket
>>>     |> assign(:myvar, params["myvar"])
>>>     |> assign_new(:some_default, fn -> 42 end)
>>>
>>>   {:noreply, socket}
>>> end
>>> ```
>>>
>>> more readable, by allowing it to be written as:
>>>
>>> ```
>>> def update(params, socket) do
>>>     socket
>>>     |> assign(:myvar, params["myvar"])
>>>     |> assign_new(:some_default, fn -> 42 end)
>>>     |> then(&{:noreply, &1})
>>> end
>>> ```
>>>
>>> This pattern seems to be common in codebases using Elixir 1.12 and up
>>> (At least according to anecdotal evidence).
>>>
>>> All is well. Except there is a little snag: The new code does not have
>>> the same runtime characteristics (both in performance and in memory usage)
>>> as `then`desugars to `(function).(value)`: An anonymous function is created
>>> and immediately run (and then garbage collected soon after).
>>>
>>> The Erlang compiler is clever enough to optimize these
>>> immediately-called anonymous functions away, but it will only do so when
>>> `@compile :inline` is set in the given module, to not mess with the call
>>> stack that might be returned when an exception is thrown.
>>>
>>> Now `@compile :inline` is quite the sledgehammer, as it will inline
>>> *all* functions in the current module (as long as they are not 'too
>>> big', which can also be configured, and only in the places where they are
>>> called statically).
>>> But since we're dealing with anonymous functions here which do not have
>>> clear names, there is no way to predict the name one should pass to the
>>> `@compile` option.
>>>
>>>
>>> It seems like this situation could be improved, although I am not sure
>>> how.
>>>
>>> Is there a way to mark these anonymous functions in some kind of way, to
>>> allow only them to be inlined?
>>> Or is there maybe a way to have the Elixir-compiler already inline
>>> common patterns like a capture with a datatype, rather than relying on the
>>> Erlang compiler for this?
>>> Your input is greatly appreciated.
>>>
>>> ~Marten/Qqwy
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to elixir-lang-core+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/elixir-lang-core/f0da2df2-432e-423c-a02b-27d8b916a0ecn%40googlegroups.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/f0da2df2-432e-423c-a02b-27d8b916a0ecn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "elixir-lang-core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to elixir-lang-core+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2Bu8RTb8sMAJyGiuw6%2BgGgyuVZVxjpFad9M%2BbEgYrwkbg%40mail.gmail.com
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2Bu8RTb8sMAJyGiuw6%2BgGgyuVZVxjpFad9M%2BbEgYrwkbg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "elixir-lang-core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to elixir-lang-core+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/elixir-lang-core/b02049e0-8d86-a7b4-e8e0-396bb9ecd4f0%40resilia.nl
>> <https://groups.google.com/d/msgid/elixir-lang-core/b02049e0-8d86-a7b4-e8e0-396bb9ecd4f0%40resilia.nl?utm_medium=email&utm_source=footer>
>> .
>
>
>> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4KqHRqTEisWYLNi7n2UQzP5XtVMUYkLbkHyiVyjcvKFOg%40mail.gmail.com
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4KqHRqTEisWYLNi7n2UQzP5XtVMUYkLbkHyiVyjcvKFOg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/84dbf8a8-4f9f-5aa7-efc3-1658e097a8c5%40resilia.nl
> <https://groups.google.com/d/msgid/elixir-lang-core/84dbf8a8-4f9f-5aa7-efc3-1658e097a8c5%40resilia.nl?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jod05LOG61Wf08gkNR0FTSDx8W4gWSZdr96k7BZ94UrQ%40mail.gmail.com.

Reply via email to