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

water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews