How much overhead is there from importing?

Ok since the beginning I have been taught that you need to import only the functions you need, in order to avoid importing EVERY function in the module:

# Do this:
import MyModule, only: [foo: 2]

# Not this:
import MyModule

But part of me always wonders how important is this, realistically?

I mean, if my server has gigabytes of memory, and I use up maybe a few kilobytes from the extra functions, and only during compilation/startup… that doesn’t sound like a big deal. Is there another reason we do this than resource usage? Name conflicts? Design patterns?

Name conflicts is what you’re protecting against, not memory usage.

4 Likes

To expand on @dimitarvp’s answer a bit, import doesn’t really “import” so much as it “opens the module up for name resolution.” All imported functions effectively get rewritten to their fully qualified versions once compiled (hence “remote” functions), they don’t get “added” to the module. This is why imported functions can’t be called as public functions elsewhere.

For me I only blanket import if the module is doing a specific type of thing (like a LiveView, for example) and then only ever have one blanket import. Otherwise, if if I’m using a function a bunch of times I’ll import and use :only so that it’s clear where it’s is coming from. Otherwise, I just alias (assuming I’m not using a macro).

6 Likes

Tangentially, I basically never import anything. I strongly prefer to use alias.

I find it’s easier to comprehend the code by reading SomeModule. some_func() than just some_func().

I think it saves my brain from having to manually compute where each function lives, and by extension, what its purpose is.

To answer the thread’s question, though, I would say “basically none”, and the idea of reducing resource usage by restricting the number of imports would be a pretty late-stage micro-optimization.

10 Likes

My point was that I don’t believe it’s even a micro-optimization. In fact in very small tests, doing a blanket import seems to reduce the .beam file’s size, I’m not sure if this is always true or not, though.

2 Likes

Me too. It makes it so much easier to understand the code.

1 Like

All the import does is cause a compilation dependency and can potentially slow compilation down if you have a module within your project that everything imports. About the only imports I do out of habit now is import Ecto.Changeset and import Ecto.Query. It’s okay for my files to have ecto as a dependency for compilation, that rarely changes.

Even then, this only true if the module contains macros or you are calling its functions at compile time. Of course, very often we are indeed importing to use macros as in the case of Ecto.Query, but as you say, that’s a library that doesn’t change often, so it’s fine. It’s good to be aware that putting custom macros in a module that changes often and is used a lot throughout your app is a recipe for a very bad time.

1 Like