
What is the .NET IL linker and what does it do? - kyoukushin
https://www.matsbraa.net/what-is-the-net-il-linker-and-what-does-it-do/
======
taspeotis
From using it with Xamarin: it’s all well and good until reflection breaks it.
Which is manageable in your own code but god help you if you pull in a third
party assembly that uses reflection and your app suddenly breaks between debug
and release configurations.

The edit-test-debug cycle for linker problems can be pretty brutal too since
compilation and linking takes longer in release than debug.

~~~
oaiey
I think it is good practice to avoid reflection as a library author. Rarely
done right and even then, often source of issues (see here).

------
MarkSweep
I’ve been meaning to write up my expirement in maximizing the amount of things
the IL linker removes:

[https://github.com/AustinWise/IlLinkerExample/blob/master/RE...](https://github.com/AustinWise/IlLinkerExample/blob/master/README.md)

If you are willing to have slower application startup times in exchange for
small code, you can disable the ahead of time code generation (crossgen). This
gets a self-contained hello world on Windows down to ~10MB. That’s not great
for a hello world, but it’s a big improvement over the ~60MB that you get
without the linker.

~~~
MaxBarraclough
Seems to me that's the sensible way to distribute an application. The user
probably has a more recent compiler in their .Net runtime, and it enables
machine-specific optimisation, right? I'm assuming it's the same compiler
either way.

It's interesting that they've blended the models traditionally used by the JVM
and by Unix.

Java: ship the IR, have the user's JIT generate machine-code at the last
minute

UNIX: ship C source, have the user compile it as part of the installation
process

.Net: ship the IR and either include machine-code too, or have the user
compile it to machine-code, either JIT or caching 'pre-JIT' at install-time
(Paint.NET does this)

I suppose the 'pre-JIT' approach precludes profile-guided optimisation though,
unless the IR is annotated with profiling data.

~~~
pjmlp
Java: ship the AOT compiled binary, when the company is willing to pay for a
3rd party JDK.

~~~
MaxBarraclough
Sure, the proprietary Excelsior JET ahead-of-time-compiling JVM is out there,
but their selling-points are obfuscation and startup-time, not long-running
performance.

OpenJDK is adding support for AOT compilation. Looks like it's still
considered experimental though.

~~~
igouy
Substrate VM

[https://benchmarksgame-
team.pages.debian.net/benchmarksgame/...](https://benchmarksgame-
team.pages.debian.net/benchmarksgame/faster/java-substratevm.html)

(same gz usually means same source code)

 _" Right now peak performance is a bit worse than HotSpot, but we don’t want
to advertise that (and we want to fix it of course)."_

[https://www.graalvm.org/docs/reference-manual/aot-
compilatio...](https://www.graalvm.org/docs/reference-manual/aot-compilation/)

------
mshockwave
similar to LLVM linker? I mean, both of them work on abstraction
representations(LLMV IR and IL) instead of working on native code directly.

------
test1235
bit off-topic, but why is it called a linker? I would have thought a more
relevant name like optimiser or pruner or something.

~~~
porpoisely
Because it's part of the linking process. The linking process brings together
dependencies to produce the final product ( an assembly in the .net world ).
The .NET IL linker may "link" the bare minimum resources necessary, but it
still links the bare minimum resources.

Also optimization, pruning, etc can happen in every stage of the building
process. Preprocessing, compiling, assembly, linking, etc can have
optimization. In .NET optimization and pruning can occur post build. The JIT
can optimize, prune, etc. Even the native code can be optimized by the
runtime. Even hardware like the CPU can perform optimization on your
executable. So optimizer or pruner would be an even more confusing name.

