svn commit: r321048 - head/sys/kern

Ian Lepore ian at FreeBSD.org
Sun Jul 16 16:54:04 UTC 2017


Author: ian
Date: Sun Jul 16 16:54:03 2017
New Revision: 321048
URL: https://svnweb.freebsd.org/changeset/base/321048

Log:
  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.

Modified:
  head/sys/kern/subr_clock.c

Modified: head/sys/kern/subr_clock.c
==============================================================================
--- head/sys/kern/subr_clock.c	Sun Jul 16 16:51:38 2017	(r321047)
+++ head/sys/kern/subr_clock.c	Sun Jul 16 16:54:03 2017	(r321048)
@@ -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 *
 	 * 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->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;
 


More information about the svn-src-all mailing list