Are module attributes "read" multiple times in same function?

Thanks for the good info.
I’m super surprised that the compiler doesn’t change %{a: 1}.a} to 1.

If you are seeing this because of “decompiled” code, keep in mind that this code is built from the debug_info or abstract_code chunks of the beam files. I am not sure those contain all optimizations done by the compiler.

3 Likes

That makes more sense.
I am honestly kind of shocked if compiler doesn’t change %{a: 1}.a to 1. That seems like the entire job of the compiler.

Here’s the code.
you can clone it GitHub - eksperimental-help/slouchpie

Unoptimized: slouchpie/foo_big.ex at main · eksperimental-help/slouchpie · GitHub

Optimized: slouchpie/foo_small.ex at main · eksperimental-help/slouchpie · GitHub

$ mix compile

$ touch lib/foo_big.ex && rm _build/dev/lib/slouchpie/ebin/Elixir.Foo.Big.beam 
$ time mix compile
Compiling 1 file (.ex)
Compiling lib/foo_big.ex (its taking more than 10s)

real  0m33.185s
user  0m28.222s
sys 0m4.836s

$ touch lib/foo_small.ex && rm _build/dev/lib/slouchpie/ebin/Elixir.Foo.Small.beam 
$ time mix compile
Compiling 1 file (.ex)

real  0m2.502s
user  0m2.306s
sys 0m0.331s

$ ls -alh _build/dev/lib/slouchpie/ebin/Elixir.Foo.*.beam
 23M Dec 15 14:14 _build/dev/lib/slouchpie/ebin/Elixir.Foo.Big.beam
2.1K Dec 15 14:15 _build/dev/lib/slouchpie/ebin/Elixir.Foo.Small.beam

$ elixir --version
Erlang/OTP 24 [erts-12.1.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.13.0 (compiled with Erlang/OTP 24)

UPDATE:

Here are the benchmarks
https://github.com/eksperimental-help/slouchpie/blob/main/benchmarks/foo.exs

Elixir 1.13.0
Erlang 24.1.2

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 5 s
parallel: 1
inputs: none specified
Estimated total run time: 24 s

Benchmarking Unoptimized: Foo.Big...
Benchmarking Optimized: Foo.Small...

Name                           ips        average  deviation         median         99th %
Optimized: Foo.Small      292.62 K        3.42 μs   ±436.00%        2.46 μs        6.48 μs
Unoptimized: Foo.Big       83.26 K       12.01 μs   ±123.18%        7.73 μs       30.17 μs

Comparison: 
Optimized: Foo.Small      292.62 K
Unoptimized: Foo.Big       83.26 K - 3.51x slower +8.59 μs

Memory usage statistics:

Name                    Memory usage
Optimized: Foo.Small         4.53 KB
Unoptimized: Foo.Big         9.09 KB - 2.01x memory usage +4.56 KB

**All measurements for memory usage were the same**
4 Likes

WOWOWOWOWOW!
That’s beautiful.
You have taught me to not have ultimate trust in the compiler now.
I really appreciate all the effort you put in to this.
I’m marking your answer as solution since I consider it the most complete answer.

1 Like

Thank you for your kind words and recognition.
I am glad I was able to help you.