I can at least explain the `{.inline.}` pragma:
Say I have two Nim files:
# foo.nim
import bar
proc getNum*(): int =
add(10, 20)
Run
# bar.nim
proc add*(a, b: int): int =
a + b
Run
Each `.nim` file is compiled to a `.c` file, which might look something like
this:
// foo.c
extern NI add__bar_456(NI a, NI b);
NI getNum__foo_123(void) {
return add__bar_456(10, 20);
}
Run
// bar.c
NI add__bar_456(NI a, NI b) {
return a + b;
}
Run
The C compiler is then invoked for each `.c` file to compile it into a `.o`
file. When compiling `foo.c` it does not know the contents of `bar.c`! This
means the compiler cannot optimise `return add__bar_456(10, 20);` into `return
10 + 20;`
Now if we annotate the `add` proc with `{.inline.}`:
# bar.nim
proc add*(a, b: int): int {.inline.} =
a + b
Run
The generated C function for `add` will appear separately in each file where
it's used, annotated with the `inline` keyword in C, which is a suggestion for
the C compiler to substitute its contents into the place where it's used
(though as long as it can see the function it might do so anyways even without
the keyword). So `foo.c` will now look like this:
// foo.c
static inline NI add__bar_456(NI a, NI b) {
return a + b;
}
NI getNum__foo_123(void) {
return add__bar_456(10, 20);
}
Run
Now the C compiler knows the implementation of `add__bar_456` when it's
compiling `foo.c`, so it will hopefully inline it like so:
NI getNum__foo_123(void) {
return 10 + 20;
}
Run
In summary: `{.inline.}` is a pragma that causes a proc to be generated
separately in each module where it's used, and annotated with C's `inline`
keyword, in the hopes that the C compiler will do the actual inlining. There's
nothing in the C standard that says the compiler
_[will](https://forum.nim-lang.org/postActivity.xml#will) do this, but it ought
to, if it deems it to be beneficial for performance, and assuming you compiled
with `-d:release` or `-d:danger`.
Needless to say, apart from tiny functions like `add`, this will increase the
size of your executable, because now the whole body of the function is copied
into the place where it's used. But it saves the cost of a function call, so if
applied to the right kinds of procs (e.g. maths functions, getters/setters and
other small procs with frequent usage) it can be great for performance.
If you don't want to worry about this though, an alternative is to enable
link-time optimisation with
[`-d:lto`](https://nim-lang.org/faq.html#which-option-to-use-for-the-fastest-executable).