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;
This commit is contained in:
Hiltjo Posthuma 2021-01-10 16:57:53 +01:00
parent c1b44cf790
commit f18f4818ed
4 changed files with 8 additions and 8 deletions

View File

@ -20,7 +20,7 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f)
char *fields[FieldLast];
ssize_t linelen;
unsigned int isnew;
struct tm *tm;
struct tm rtm, *tm;
time_t parsedtime;
/* menu if not unnamed */
@ -42,7 +42,7 @@ printfeed(FILE *fpitems, FILE *fpin, 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;

View File

@ -41,7 +41,7 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f)
char *fields[FieldLast], *itemhost, *itemport, *itempath;
ssize_t linelen;
unsigned int isnew;
struct tm *tm;
struct tm rtm, *tm;
time_t parsedtime;
int itemtype;
@ -81,7 +81,7 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f)
parsedtime = 0;
if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
(tm = localtime(&parsedtime))) {
(tm = localtime_r(&parsedtime, &rtm))) {
isnew = (parsedtime >= comparetime) ? 1 : 0;
f->totalnew += isnew;

View File

@ -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;

View File

@ -16,7 +16,7 @@ static void
printfeed(FILE *fp, const char *feedname)
{
char *fields[FieldLast];
struct tm *tm;
struct tm rtm, *tm;
time_t parsedtime;
ssize_t linelen;
@ -27,7 +27,7 @@ printfeed(FILE *fp, const char *feedname)
parsedtime = 0;
if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
(tm = localtime(&parsedtime))) {
(tm = localtime_r(&parsedtime, &rtm))) {
if (parsedtime >= comparetime)
fputs("N ", stdout);
else