Inlining of C# functions

  • Thread starter Thread starter Sheila Jones
  • Start date Start date
S

Sheila Jones

Hello,

Can anybody tell me if the C# compiler will automatically inline simple
functions? To be specific, given:

double RadiansToDegrees(double degrees) {
return degrees*180.0/Math.PI;
}

will something like
y = RadiansToDegrees(x);
be compiled as
y = x*180.0/Math.PI;
rather than a function call?

Also, am I correct to assume that 180.0/Math.PI will be evaluated at compile
time rather than run time?

Thanks.
 
Sheila Jones said:
Hello,

Can anybody tell me if the C# compiler will automatically inline simple
functions? To be specific, given:

double RadiansToDegrees(double degrees) {
return degrees*180.0/Math.PI;
}

will something like
y = RadiansToDegrees(x);
be compiled as
y = x*180.0/Math.PI;
rather than a function call?
It will be compiled as a function call, but the JIT is free to inline the
code it generates. It probably will considering the simplicitly of method.
Also, am I correct to assume that 180.0/Math.PI will be evaluated at compile
time rather than run time?
I don't know, off hand, although I would suspect so. I'd suggest taking a
trip through ILDasm with a bit of code that does it and see.
 
Yes, the JIT compiler will inline your method as it sees
fit to inline it UNLESS your class, or one of its base
classes, descends from the System.MarshalByReference
class. The System.MarshalByReference class suppresses all
inlining for descendants...

--Richard
 
Richard said:
Yes, the JIT compiler will inline your method as it sees
fit to inline it UNLESS your class, or one of its base
classes, descends from the System.MarshalByReference
class. The System.MarshalByReference class suppresses all
inlining for descendants...
That would actually be System.MarshalByRefObject, ;).
 
So there is definitely no C# equivalent to the C++ 'inline' (or even
'__forceinline') specifier, to be absolutely sure it's inlined? I don't want
the overhead of a function call just to do a multiplication. The only reason
I've written it as a function is to make the code a bit more understandable.

Could you also clarify another point for me? Does code in a CLR program get
re-compiled each time the program is run, or just the first time?

Thanks.
 
Sheila Jones said:
So there is definitely no C# equivalent to the C++ 'inline' (or even
'__forceinline') specifier, to be absolutely sure it's inlined? I don't want
the overhead of a function call just to do a multiplication. The only reason
I've written it as a function is to make the code a bit more understandable.
No, there is no such keyword. However, if your method is under 32bytes(I
think) of IL, doesn't use complex flow control(anything other than if), and
sealed\non-virtual, chances are really rather high(possibly guarenteed?)
that the method will be inlined. .
Could you also clarify another point for me? Does code in a CLR program get
re-compiled each time the program is run, or just the first time?
They are usually JIT compiled on each run, you can run ngen.exe to
pre-compile it, but they pre-compiled image may be thrown out under certain
circumstances.
 
Thank you for your reply. It sounds like my function will almost certainly
be inlined.

32 bytes doesn't sound very much though, but I suppose IL is quite compact.
 
Sheila Jones said:
Thank you for your reply. It sounds like my function will almost certainly
be inlined.

32 bytes doesn't sound very much though, but I suppose IL is quite compact.
I could be wrong on the exact number, but IL is rather compact. Inlining is
designed for small methods however, basically things that are small enough
that they don't exceed(significantly) the cost of the call. Most likely if
your method is complicated enough that it exceeds 32 bytes, chances are its
too expensive for the method call to matter.

However, I would like to see the JIT be able to inline method calls that are
virtual when possible, I imagine that may come eventually(some Java vm's do
it as I understand).
 
Daniel O'Connell said:
However, I would like to see the JIT be able to inline method calls that are
virtual when possible, I imagine that may come eventually(some Java vm's do
it as I understand).

The Hotspot JVM is able to do so, but only because it made the decision
to be able to recompile when situations change (usually when the code
is run frequently, so it's worth applying more aggressive
optimisations, but also when assumptions are invalidated so some
optimisation has to be *undone*).

The current CLR JIT is a "one time" JIT - once the code is generated,
it's never changed as far as I'm aware. This has benefits and
drawbacks, of course, but I suspect it's unlikely to change in the near
future.
 
Jon Skeet said:
The Hotspot JVM is able to do so, but only because it made the decision
to be able to recompile when situations change (usually when the code
is run frequently, so it's worth applying more aggressive
optimisations, but also when assumptions are invalidated so some
optimisation has to be *undone*).

The current CLR JIT is a "one time" JIT - once the code is generated,
it's never changed as far as I'm aware. This has benefits and
drawbacks, of course, but I suspect it's unlikely to change in the near
future.
I'll admit it seems unlikely in the foreseeable future(but with luck .NET
will survive, in some form, as long as java has), but projects like mono and
rotor may produce worthy ideas as well. I doubt that the Hotspot method is
the only way, even if its the only way thats currently practical. Of course,
this will only matter if the .NET market opens up with more vendors than
Mono and MS, its pretty unlikely that a mono change will ever make it up
into the MS.NET market and fairly unlikely that mono will ever be a leader
in functionalitity, however it does give bored developers somethign to play
with.
 
Back
Top