Adding environment variables can become quite expensive in some
admittedly unlikely situations.

    $ for i in $(seq 10000); do export A$i=A$i; done
    $ time ./src/date-prev -u $(yes -- -u | head -n 100000)
    Sun Mar 29 01:59:49 AM UTC 2026

    real        0m3.753s
    user        0m3.684s
    sys 0m0.050s
    $ time ./src/date -u $(yes -- -u | head -n 100000)
    Sun Mar 29 02:00:00 AM UTC 2026

    real        0m0.061s
    user        0m0.022s
    sys 0m0.045s

* src/date.c (main): Only add TZ=UTC0 to the environment once.
---
 src/date.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/date.c b/src/date.c
index e53566729..d37fb5712 100644
--- a/src/date.c
+++ b/src/date.c
@@ -483,6 +483,7 @@ main (int argc, char **argv)
   char *reference = NULL;
   bool discarded_datestr = false;
   bool discarded_set_datestr = false;
+  bool utc = false;
 
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
@@ -559,12 +560,7 @@ main (int argc, char **argv)
           set_date = true;
           break;
         case 'u':
-          /* POSIX says that 'date -u' is equivalent to setting the TZ
-             environment variable, so this option should do nothing other
-             than setting TZ.  */
-          if (putenv (bad_cast ("TZ=UTC0")) != 0)
-            xalloc_die ();
-          TZSET;
+          utc = true;
           break;
         case_GETOPT_HELP_CHAR;
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -573,6 +569,16 @@ main (int argc, char **argv)
         }
     }
 
+  if (utc)
+    {
+      /* POSIX says that 'date -u' is equivalent to setting the TZ
+         environment variable, so this option should do nothing other
+         than setting TZ.  */
+      if (putenv (bad_cast ("TZ=UTC0")) != 0)
+        xalloc_die ();
+      TZSET;
+    }
+
   int option_specified_date = (!!datestr + !!batch_file + !!reference
                                + get_resolution);
 
-- 
2.53.0


Reply via email to