Sometimes I want to add more typesafety around raw doubles. One idea that comes up a lot would be adding unit information with the types. For example,
struct AngleRadians {
public readonly double Value;
/* Constructor, casting operator to AngleDegrees, etc omitted for brevity... */
}
In the case like above, where there is only a single field, will the JIT be able to optimize away this abstraction in all cases? What situations, if any, will result in extra generated machine instructions compared to similar code using an unwrapped double?
Any mention of premature optimization will be downvoted. I'm interested in knowing the ground truth.
Edit: To narrow the scope of the question, here are a couple of scenarios of particular interest...
// 1. Is the value-copy constructor zero cost?
// Is...
var angleRadians = new AngleRadians(myDouble);
// The same as...
var myDouble2 = myDouble;
// 2. Is field access zero cost?
// Is...
var myDouble2 = angleRadians.Value;
// The same as...
var myDouble2 = myDouble;
// 3. Is function passing zero cost?
// Is calling...
static void DoNaught(AngleRadians angle){}
// The same as...
static void DoNaught(double angle){}
// (disregarding inlining reducing this to a noop
These are some of the things I can think of off the top of my head. Of course, an excellent language designer like @EricLippert will likely think of more scenarios. So, even if these typical use cases are zero-cost, I still think it would be good to know if there is any case where the JIT doesn't treat a struct holding one value, and the unwrapped value as equivalent, without listing each possible code snippet as it's own question
AngleDegrees
,AngleRadians
,AngleGradians
and so on is a bad idea. Have oneAngle
type which has propertiesAsDegrees
,AsRadians
, and so on, and factoriesFromRadians
, and so on. The implementation details of your type are just that: implementation details. By embedding the implementation detail in the name of the type you restrict your ability to innovate and lower the level of abstraction. – Damronreadonly
is one way of possibly tripping over hidden costs. Take it away, Jon Skeet. (Note that this post is quite old, though, and pre-RyuJIT. It could do with some verification to see if this still happens. And in that vein, any question that asks "will the JIT do this or that" has to be taken with the extreme caveat "you really won't know until you test, and even if you do your results may be invalid tomorrow". The JIT compiler does not adhere to a formal spec guaranteeing stuff.) – Eleusis