belaustegui

belaustegui

When I compile my application, I see a lot of messages like:

Compiling some/module/file.ex (it’s taking more than 10s)

I understand that this message is appearing because the compilation of those modules is slow, but I don’t know why is this and where to start looking for possible causes. Any suggestions?

Showing Posts 1 to 10

NobbZ

NobbZ

Is your project public?

Modules are known to take long when you have a lot of macrocalls or functions with a lot of heads. Before 1.5.somewhat compile time of a function grew squared to its number of heads. I’m not sure when this was fixed (or if at all, maybe fix is master only)

belaustegui

belaustegui OP

Unfortunately no. It belongs to the company I am working for.

I don’t know if it has something to do with it, but in the 95% of those warnings, the affected module is a controller or a view.

wojtekmach

wojtekmach

Hex Core Team

Another reason for slow compilation is if given module depends on other slow modules. [1] Is a great resource for understanding compilation. In general, you want to avoid compile-time dependencies between modules as much as possible.

On our Phoenix app, switching from import MyApp.Router.Helpers to alias MyApp.Router.Helpers, as: Routes speed up compilation and limited re-compilations greatly, see: [2]

Elixir 1.6 will ship with improvements to mix xref which should make it easier to investigate this stuff.

[1] http://milhouseonsoftware.com/2016/08/11/understanding-elixir-recompilation/
[2] Do not set compile time dependencies on the router · Issue #2530 · phoenixframework/phoenix · GitHub
[3] elixir/CHANGELOG.md at main · elixir-lang/elixir · GitHub

belaustegui

belaustegui OP

Hm, we may have something here :thinking:
Running mix xref graph --source on those slow modules usually shows the router as a compile time dependency, which in turn depends on lots of controllers, which depend on models, etc.

I am going to try aliasing the router module instead of importing it and check the result.
Thank you @wojtekmach

a-maze-d

a-maze-d

I know this is an old thread but I came across it, because I also got the it's taking more than 10s message during compilation. In my case I do know exactly the reason for that long compilation time and there is nothing really I can do about it (I did try a lot of things to eliminate it, but it wasn’t possible).

Thus, I can either just accept the message or try to disable that (meaningful) warning. I didn’t find any real answer on how to disable the warning. And yes, you should first try to fix your dependencies as mentioned above, but if you might want to disable it. Hence the reason for my comment and to share what I found out :slight_smile:

By going through the elixir code I could figure out that there is actually a compiler setting (:long_compilation_threshold) that can disable it (or be adjusted). In your mix.exs you just add the following line into your project/0 function:

 def project do
    [
      ...
      elixirc_options: [long_compilation_threshold: 60_000],
      ...
    ]
  end

This removed it for me :slight_smile: . Don’t ask me as from which version this flag is available, thus, it might not work if you are on an old Elixir version.

If you want to see where I used it, feel free to play around with my repo, you can find it here:

BartOtten

BartOtten

A possible partial fix

instead of using multiple function heads

def fun(a, :foo = b), do: :alpha 
def fun(a, :bar = b), do: :beta

you can help the compiler by making it one function head with embedded case statement:

def fun (a, b) do
  case b do
   :foo -> :alpha 
   :bar -> :beta
end

Routex was not able to build helper functions for 400 (generated) routes causing “too complex” issues during compilation due to the amount of generated function heads. In the upcoming version 1.2 those are rewritten to case statement variants and it now handles more than 2.000 routes.

D4no0

D4no0

I would say this is a great optimisation if you are generating the code with metaprogramming.

Otherwise I would almost always recommend to take the most readable approach. There was a similar discussion on similar topics such as how map.key is very inefficient compared to pattern-matching.

This is a implementation detail that can be changed anytime in the future and should not be a concern of the end-user that is the developer.

BartOtten

BartOtten

Yes. I do not expect this for manually written code. If you write 400 function heads yourself, you might be the limit yourself :wink:

Fully agree with your advice

D4no0

D4no0

It can happen and I’ve worked in a codebase where we had such files that had many function heads, maintained by hand.

The thing is that, while most of those function heads were just returning constants, at some point, a new set of features introduced processing. Doing that kind of thing using case is much more inconvenient from readability standpoint.

a-maze-d

a-maze-d

Yes, this works for those cases where you don’t mind too much about the function signature, but in my case I do want to provide an easier/more convenient interface for the user. It’s just so much nicer to write:

leds(20) |> red |> green |> blue

Than to write the alternative (even though my library does support both):

leds(20) |> light(:red) | light(:green) |> light(blue)

At the end it’s the libraries decision. I didn’t want to start a discussion on what the right way is (and yes, there are many reasons to not hide issues by using this trick), but only that, if you want to get rid of the warning, you could do so with the compile flag.

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews