title: Why are DateTime.Now DateTime.UtcNow so slow/expensive
body: <p>I realize this is way too far into the micro-optimization area, but I am curious to understand why Calls to DateTime.Now and DateTime.UtcNow are so "expensive". I have a sample program that runs a couple of scenarios of doing some "work" (adding to a counter) and attempts to do this for 1 second. I have several approached of making it do the work for a limited quantity of time. The examples show that DateTime.Now and DateTime.UtcNow are significantly slower than Environment.TickCount, but even that is slow compared to just letting a separate thread sleep for 1 second and then setting a value to indicate the worker thread to stop.</p>
  
  <p>So my questions are these:</p>
  
  <ul>
  <li>I know that UtcNow is faster because it does not have time zone information, why is it still so much slower than TickCount?</li>
  <li>Why is reading a boolean faster than an int?</li>
  <li>What is the ideal way of dealing with these types of scenarios where you need to allow something to run for a limited amount of time, but you do not want to waste more time checking the time than actually doing the work?</li>
  </ul>
  
  <p>Please pardon the verbosity of the example:</p>
  
  <pre><code>class Program
  {
      private static volatile bool done = false;
      private static volatile int doneInt = 0;
      private static UInt64 doneLong = 0;
  
      private static ManualResetEvent readyEvent = new ManualResetEvent(false);
  
      static void Main(string[] args)
      {
          MethodA_PrecalcEndTime();
          MethodB_CalcEndTimeEachTime();
          MethodC_PrecalcEndTimeUsingUtcNow();
  
          MethodD_EnvironmentTickCount();
  
          MethodX_SeperateThreadBool();
          MethodY_SeperateThreadInt();
          MethodZ_SeperateThreadLong();
  
          Console.WriteLine("Done...");
          Console.ReadLine();
      }
  
      private static void MethodA_PrecalcEndTime()
      {
          int cnt = 0;
          var doneTime = DateTime.Now.AddSeconds(1);
          var startDT = DateTime.Now;
          while (DateTime.Now &lt;= doneTime)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void MethodB_CalcEndTimeEachTime()
      {
          int cnt = 0;
          var startDT = DateTime.Now;
          while (DateTime.Now &lt;= startDT.AddSeconds(1))
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void MethodC_PrecalcEndTimeUsingUtcNow()
      {
          int cnt = 0;
          var doneTime = DateTime.UtcNow.AddSeconds(1);
          var startDT = DateTime.Now;
          while (DateTime.UtcNow &lt;= doneTime)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
  
      private static void MethodD_EnvironmentTickCount()
      {
          int cnt = 0;
          int doneTick = Environment.TickCount + 1000; // &lt;-- should be sane near where the counter clocks...
          var startDT = DateTime.Now;
          while (Environment.TickCount &lt;= doneTick)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void MethodX_SeperateThreadBool()
      {
          readyEvent.Reset();
          Thread counter = new Thread(CountBool);
          Thread waiter = new Thread(WaitBool);
          counter.Start();
          waiter.Start();
          waiter.Join();
          counter.Join();
      }
  
      private static void CountBool()
      {
          int cnt = 0;
          readyEvent.WaitOne();
          var startDT = DateTime.Now;
          while (!done)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void WaitBool()
      {
          readyEvent.Set();
          Thread.Sleep(TimeSpan.FromSeconds(1));
          done = true;
      }
  
      private static void MethodY_SeperateThreadInt()
      {
          readyEvent.Reset();
          Thread counter = new Thread(CountInt);
          Thread waiter = new Thread(WaitInt);
          counter.Start();
          waiter.Start();
          waiter.Join();
          counter.Join();
      }
  
      private static void CountInt()
      {
          int cnt = 0;
          readyEvent.WaitOne();
          var startDT = DateTime.Now;
          while (doneInt&lt;1)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void WaitInt()
      {
          readyEvent.Set();
          Thread.Sleep(TimeSpan.FromSeconds(1));
          doneInt = 1;
      }
  
      private static void MethodZ_SeperateThreadLong()
      {
          readyEvent.Reset();
          Thread counter = new Thread(CountLong);
          Thread waiter = new Thread(WaitLong);
          counter.Start();
          waiter.Start();
          waiter.Join();
          counter.Join();
      }
  
      private static void CountLong()
      {
          int cnt = 0;
          readyEvent.WaitOne();
          var startDT = DateTime.Now;
          while (doneLong &lt; 1)
          {
              cnt++;
          }
          var endDT = DateTime.Now;
          Console.WriteLine("Time Taken: {0,30} Total Counted: {1,20}", endDT.Subtract(startDT), cnt);
      }
  
      private static void WaitLong()
      {
          readyEvent.Set();
          Thread.Sleep(TimeSpan.FromSeconds(1));
          doneLong = 1;
      }
  
  }
  </code></pre>