Minor optimization: instead of converting between days and years using loops

that start in 1970, assume most conversions are going to be for recent dates
and use a precomputed number of days through the end of 2016.

This is a do-over of r320997, hopefully this time with 100% more workiness.

The first attempt had an off-by-one error, but instead of just adding
another mysterious +1 adjustment, this rearranges the relationship between
recent_base_year and recent_base_days so that the latter is the number of
days that occurred before the start of the associated year (instead of the
count thru the end of that year).  This makes the recent_base stuff work
more like the original loop logic that didn't need any +1 adjustments.
This commit is contained in:
Ian Lepore 2017-07-16 16:54:03 +00:00
parent 7582669623
commit f7afe7679c

View File

@ -97,6 +97,13 @@ static const int month_days[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/*
* Optimization: using a precomputed count of days between POSIX_BASE_YEAR and
* some recent year avoids lots of unnecessary loop iterations in conversion.
* recent_base_days is the number of days before the start of recent_base_year.
*/
static const int recent_base_year = 2017;
static const int recent_base_days = 17167;
/*
* This inline avoids some unnecessary modulo operations
@ -157,8 +164,14 @@ clock_ct_to_ts(struct clocktime *ct, struct timespec *ts)
* Compute days since start of time
* First from years, then from months.
*/
days = 0;
for (i = POSIX_BASE_YEAR; i < year; i++)
if (year >= recent_base_year) {
i = recent_base_year;
days = recent_base_days;
} else {
i = POSIX_BASE_YEAR;
days = 0;
}
for (; i < year; i++)
days += days_in_year(i);
/* Months */
@ -188,8 +201,14 @@ clock_ts_to_ct(struct timespec *ts, struct clocktime *ct)
ct->dow = day_of_week(days);
/* Subtract out whole years, counting them in i. */
for (year = POSIX_BASE_YEAR; days >= days_in_year(year); year++)
/* Subtract out whole years. */
if (days >= recent_base_days) {
year = recent_base_year;
days -= recent_base_days;
} else {
year = POSIX_BASE_YEAR;
}
for (; days >= days_in_year(year); year++)
days -= days_in_year(year);
ct->year = year;