Herong's Tutorial Notes On C# - Part B
Dr. Herong Yang, Version 2.02

Performance of 'float', 'double', and 'decimal'

In order to find out how much extra time an arithmetic operation will take on decimal type comparing to the float and double types, I wrote the following program:

using System;
class TimeReals {
   static void Main() {
      long m = 100000;
      long n = 100;
     
      float fs = 1.0f/3.0f;
      float ff = 2.0f/3.0f;
      float fi = fs;
      TimeSpan fd = LoopFloat(m, n, ref fs, ref ff);
      Console.WriteLine("Float: time = {0} ", fd);
      Console.WriteLine(" Input = {0} ", fi);
      Console.WriteLine(" Output = {0} ", fs);

      double ds = 1.0d/3.0d;
      double df = 2.0d/3.0d;
      double di = ds;
      TimeSpan dd = LoopDouble(m, n, ref ds, ref df);
      Console.WriteLine("Double: time = {0} ", dd);
      Console.WriteLine(" Input = {0} ", di);
      Console.WriteLine(" Output = {0} ", ds);

      decimal ms = 1.0m/3.0m;
      decimal mf = 2.0m/3.0m;
      decimal mi = ms;
      TimeSpan md = LoopDecimal(m, n, ref ms, ref mf);
      Console.WriteLine("Decimal: time = {0} ", md);
      Console.WriteLine(" Input = {0} ", mi);
      Console.WriteLine(" Output = {0} ", ms);

      Console.WriteLine("Accuracy:");
      Console.WriteLine(" Float = {0} ", (fs-fi)/fi);
      Console.WriteLine(" Double = {0} ", (ds-di)/di);
      Console.WriteLine(" Decimal = {0} ", (ms-mi)/mi);
      
      Console.WriteLine("Performance:");
      Console.WriteLine(" Float = {0} ", 
         fd.TotalMilliseconds/dd.TotalMilliseconds);
      Console.WriteLine(" Double = {0} ", 
         dd.TotalMilliseconds/dd.TotalMilliseconds);
      Console.WriteLine(" Decimal = {0} ", 
         md.TotalMilliseconds/dd.TotalMilliseconds);
   }
   private static TimeSpan LoopFloat(long m, long n, 
      ref float s, ref float f) {
      long i, j;
      DateTime t1 = DateTime.UtcNow;
      for (i=1; i<=m; i++) {
         for (j=1; j<=n; j++) {
            s = s*f;
         }
         for (j=1; j<=n; j++) {
            s = s/f;
         }
      }
      DateTime t2 = DateTime.UtcNow;
      TimeSpan duration = t2.Subtract(t1);
      return duration;
   }
   private static TimeSpan LoopDouble(long m, long n, 
      ref double s, ref double f) {
      long i, j;
      DateTime t1 = DateTime.UtcNow;
      for (i=1; i<=m; i++) {
         for (j=1; j<=n; j++) {
            s = s*f;
         }
         for (j=1; j<=n; j++) {
            s = s/f;
         }
      }
      DateTime t2 = DateTime.UtcNow;
      TimeSpan duration = t2.Subtract(t1);
      return duration;
   }
   private static TimeSpan LoopDecimal(long m, long n, 
      ref decimal s, ref decimal f) {
      long i, j;
      DateTime t1 = DateTime.UtcNow;
      for (i=1; i<=m; i++) {
         for (j=1; j<=n; j++) {
            s = s*f;
         }
         for (j=1; j<=n; j++) {
            s = s/f;
         }
      }
      DateTime t2 = DateTime.UtcNow;
      TimeSpan duration = t2.Subtract(t1);
      return duration;
   }
}

Output:

Float: time = 00:00:00.8412264
 Input = 0.3333333
 Output = 0.3333334
Double: time = 00:00:01.0014600
 Input = 0.333333333333333
 Output = 0.333333333333333
Decimal: time = 00:00:27.5301354
 Input = 0.3333333333333333333333333333
 Output = 0.3333333333158765326639153057
Accuracy:
 Float = 1.788139E-07
 Double = -9.99200722162641E-16
 Decimal = -5.23704020082540828E-11
Performance:
 Float = 0.84
 Double = 1
 Decimal = 27.49

Question 1: Why it takes almost the same mount of time for the float type as the double type?

This is understanble. I guess that today's processors are designed with double type data as default. An arithmetic operation of the double data type requires probably the same number of processing cycles as the float data type at the machine level.

Question 2: Why takes about 27 times longer for the decimal data type than the double data type?

I don't have a good answer.

Question 3: Why the result of the decimal data type is much less accurate than the double data type?

This is big supprise to me. Can any one answer this?

If you are a designer, wait for a good answer to this question before allowing any developer to use "decimal".

Dr. Herong Yang, updated in 2002
Herong's Tutorial Notes On C# - Part B - Performance of 'float', 'double', and 'decimal'