Program size, linking matter, and static this()

Jonathan M Davis jmdavisProg at gmx.com
Fri Dec 16 11:41:30 PST 2011


On Friday, December 16, 2011 12:29:18 Andrei Alexandrescu wrote:
> Jonathan, could I impose on you to replace all static cdtors in
> std.datetime with lazy initialization? I looked through it and it
> strikes me as a reasonably simple job, but I think you'd know better
> what to do than me.
> 
> A similar effort could be conducted to reduce or eliminate static cdtors
> from druntime. I made the experiment of commenting them all, and that
> reduced the size of the baseline from 218KB to 200KB. This is a good
> amount, but not as dramatic as what we can get by working on std.datetime.

Hmm. I had reply for this already, but it seems to have disappeared, so I'll 
try again.

You could make core.time use property functions instead of the static 
immutable variables that it's using now for ticksPerSec and appOrigin, but in 
order to do that right would require introducing a mutex or synchronized block 
(which is really just a mutex under the hood anyway), and I'm loathe to do 
that in time-related code. ticksPerSec gets used all over the place in 
TickDuration, and that could have a negative impact on performance for 
something that needs to be really fast (since it's used in stuff like StopWatch 
and benchmarking). On top of that, in order to maintain the current semantics, 
the property functions would have to be pure, which they can't be without 
doing some nasty casting to convince the compiler that stuff which isn't pure 
is actually pure.

For std.datetime, the problem would be reduced if a class could be created in 
CTFE and still be around at runtime, but we can't do that yet, and it wouldn't 
completely solve the problem, since the shared static constructor related to 
LocalTime has to call tzset. So, some sort of runtime initialization must be 
done. And the instances for the singleton are not only immutable, but the 
functions for getting them are pure. So, once again, some nasty casting would 
be required to get it to work without breaking purity. And once again, we'd 
have introduce a mutex. And for both core.time and std.datetime we're talking 
about a mutex would be needed only briefly to ensure that we don't end up with 
two threads trying to initialize the variable at the same time. After that, it 
would just be impeding performance for no value. They're classic situations 
for static constructors - initializing static immutable variables - and 
really, they _should_ be using static constructors. If we have to get rid of 
them, it's to get around other problems in the language or compiler instead of 
fixing those problems. So, on some level, that seems like a failure on the part 
of the language and the compiler. If we _have_ to find a workaround, then we 
have to find a workaround, but I find the need to be distasteful to say the 
least. I previously tried to get rid of the static constructors in 
std.datetime and couldn't precisely because they're needed unless you play 
major casting games to get around immutable and pure.

If we play nice, it's impossible to get rid of the static constructors in 
std.datetime. It probably is possible if we do nasty casting, but (much as I 
hate to use the word) it seems like this is a hack to get around the fact that 
the compiler isn't dealing with static constructors as well as we'd like. I'd 
_really_ like to see this fixed at the compiler level.

And honestly, I think that a far worse problem with static constructors is 
circular dependencies. _That_ is something that needs to be addressed with 
regards to static constructors. In general at this point, it's looking like 
static constructors are turning out to be a bit of a failure on some level, 
given the issues that we're having because of them, and I think that we should 
fix the language and/or compiler so that they _aren't_ a failure.

- Jonathan M Davis


More information about the Digitalmars-d mailing list