From f18f4818ed2c992aa9b7b91c74bb9ce7cc1bc745 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Sun, 10 Jan 2021 16:57:53 +0100 Subject: optimize converting UNIX timestamp to localtime Make a huge difference (cuts the time in half to process the same amount of lines) on atleast glibc 2.30 on Void Linux. Seems to make no difference on OpenBSD. - This removes atleast one heap allocation per line (checked with valgrind). This is because glibc will strdup() the environment variable $TZ and free it each time, which is pointless here and wasteful. - localtime_r does not require to set the variables like tzname. In glibc-2.30/time/tzset.c in __tz_convert is the following code and comment: /* Update internal database according to current TZ setting. POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname. This is a good idea since this allows at least a bit more parallelism. */ tzset_internal (tp == &_tmbuf && use_localtime); This makes it always tzset() and inspect the environment $TZ etc. While with localtime_r it will only initialize it once: static void tzset_internal (int always) { [...] if (is_initialized && !always) return; --- sfeed_html.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sfeed_html.c') diff --git a/sfeed_html.c b/sfeed_html.c index 911a01b..d1e1b63 100644 --- a/sfeed_html.c +++ b/sfeed_html.c @@ -19,7 +19,7 @@ static void printfeed(FILE *fp, struct feed *f) { char *fields[FieldLast]; - struct tm *tm; + struct tm rtm, *tm; time_t parsedtime; unsigned int isnew; ssize_t linelen; @@ -42,7 +42,7 @@ printfeed(FILE *fp, struct feed *f) parsedtime = 0; if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) && - (tm = localtime(&parsedtime))) { + (tm = localtime_r(&parsedtime, &rtm))) { isnew = (parsedtime >= comparetime) ? 1 : 0; totalnew += isnew; f->totalnew += isnew; -- cgit v1.2.3