Advertisement
luisperezphd

Max versus inline versus if

Jul 16th, 2015
564
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.69 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Threading;
  4.  
  5. namespace ProfileMathMax
  6. {
  7.     class Program
  8.     {
  9.         static double controlTotalSeconds;
  10.         const uint InnerLoopCount = 100000;
  11.         const uint OuterLoopCount = 4000000000 / InnerLoopCount; // increased by x4
  12.         static int[] values = new int[InnerLoopCount];
  13.         static int total = 0;
  14.  
  15.         static void ProfileBase()
  16.         {
  17.             var stopwatch = new Stopwatch();
  18.             stopwatch.Start();
  19.             int maxValue;
  20.             for (int j = 0; j < OuterLoopCount; j++)
  21.             {
  22.                 maxValue = 0;
  23.                 for (int i = 0; i < InnerLoopCount; i++)
  24.                 {
  25.                     // baseline
  26.                     total += values[i];
  27.                 }
  28.             }
  29.             stopwatch.Stop();
  30.             controlTotalSeconds = stopwatch.Elapsed.TotalSeconds;
  31.             Console.WriteLine("Control - Empty Loop - " + controlTotalSeconds + " seconds");
  32.         }
  33.  
  34.         static double ProfileMathMax()
  35.         {
  36.             int maxValue;
  37.             Stopwatch stopwatch = new Stopwatch();
  38.             stopwatch.Start();
  39.             for (int j = 0; j < OuterLoopCount; j++)
  40.             {
  41.                 maxValue = 0;
  42.                 for (int i = 0; i < InnerLoopCount; i++)
  43.                 {
  44.                     maxValue = Math.Max(values[i], maxValue);
  45.                     total += values[i];
  46.                 }
  47.             }
  48.             stopwatch.Stop();
  49.             Console.WriteLine("Math.Max(a, max) - " + stopwatch.Elapsed.TotalSeconds + " seconds");
  50.             Console.WriteLine("Relative: " + (stopwatch.Elapsed.TotalSeconds - controlTotalSeconds)  + " seconds");
  51.             return stopwatch.Elapsed.TotalSeconds;
  52.         }
  53.  
  54.         static double ProfileMathMaxReverse()
  55.         {
  56.             int maxValue;
  57.             Stopwatch stopwatch = new Stopwatch();
  58.             stopwatch.Start();
  59.             for (int j = 0; j < OuterLoopCount; j++)
  60.             {
  61.                 maxValue = 0;
  62.                 for (int i = 0; i < InnerLoopCount; i++)
  63.                 {
  64.                     maxValue = Math.Max(maxValue, values[i]);
  65.                     total += values[i];
  66.                 }
  67.             }
  68.             stopwatch.Stop();
  69.             Console.WriteLine("Math.Max(max, a) - " + stopwatch.Elapsed.TotalSeconds + " seconds");
  70.             Console.WriteLine("Relative: " + (stopwatch.Elapsed.TotalSeconds - controlTotalSeconds)  + " seconds");
  71.             return stopwatch.Elapsed.TotalSeconds;
  72.         }
  73.  
  74.         static double ProfileInline()
  75.         {
  76.             int maxValue = 0;
  77.             Stopwatch stopwatch = new Stopwatch();
  78.             stopwatch.Start();
  79.             for (int j = 0; j < OuterLoopCount; j++)
  80.             {
  81.                 maxValue = 0;
  82.                 for (int i = 0; i < InnerLoopCount; i++)
  83.                 {
  84.                     maxValue = maxValue > values[i] ? values[i] : maxValue;
  85.                     total += values[i];
  86.                 }
  87.             }
  88.             stopwatch.Stop();
  89.             Console.WriteLine("max = max > a ? a : max: " + stopwatch.Elapsed.TotalSeconds + " seconds");
  90.             Console.WriteLine("Relative: " + (stopwatch.Elapsed.TotalSeconds - controlTotalSeconds)  + " seconds");
  91.             return stopwatch.Elapsed.TotalSeconds;
  92.         }
  93.  
  94.         static double ProfileIf()
  95.         {
  96.             int maxValue = 0;
  97.             Stopwatch stopwatch = new Stopwatch();
  98.             stopwatch.Start();
  99.             for (int j = 0; j < OuterLoopCount; j++)
  100.             {
  101.                 maxValue = 0;
  102.                 for (int i = 0; i < InnerLoopCount; i++)
  103.                 {
  104.                     if (values[i] > maxValue)
  105.                         maxValue = values[i];
  106.                     total += values[i];
  107.                 }
  108.             }
  109.             stopwatch.Stop();
  110.             Console.WriteLine("if (a > max) max = a: " + stopwatch.Elapsed.TotalSeconds + " seconds");
  111.             Console.WriteLine("Relative: " + (stopwatch.Elapsed.TotalSeconds - controlTotalSeconds)  + " seconds");
  112.             return stopwatch.Elapsed.TotalSeconds;
  113.         }
  114.  
  115.         static void Main(string[] args)
  116.         {
  117.             Console.WriteLine("Version 2.1");
  118.  
  119.             // wait one second to prime it - make sure everything .NET needs to run is loaded
  120.             Thread.Sleep(1000);
  121.  
  122.             Random rnd = new Random();
  123.  
  124.             // run twice again to prime it - make sure any optimizations the processor does for code is done
  125.             ProfileBase();
  126.             Thread.Sleep(1000);
  127.             ProfileBase();
  128.  
  129.             Console.WriteLine();
  130.  
  131.             Console.WriteLine("Running Worse Case...");
  132.             for (int i = 0; i < InnerLoopCount; i++)
  133.             {
  134.                 values[i] = i;  // worst case: every new number biggest than the previous
  135.                 //values[i] = i == 0 ? 1 : 0;  // best case: first number is the maximum
  136.                 //values[i] = rnd.Next(int.MaxValue);  // average case: random numbers
  137.             }
  138.  
  139.             var worseCase = PerformTests();
  140.  
  141.             Console.WriteLine("Running Best Case");
  142.             for (int i = 0; i < InnerLoopCount; i++)
  143.             {
  144.                 values[i] = i == 0 ? 1 : 0;  // best case: first number is the maximum
  145.             }
  146.             var bestCase = PerformTests();
  147.  
  148.             Console.WriteLine("Running Average...");
  149.             for (int i = 0; i < InnerLoopCount; i++)
  150.             {
  151.                 values[i] = rnd.Next(int.MaxValue);  // average case: random numbers
  152.             }
  153.            
  154.             var average = PerformTests();
  155.  
  156.             //var relativeTo = controlTotalSeconds;
  157.             var relativeTo = Min(
  158.                 worseCase.mathMax,
  159.                 bestCase.mathMax,
  160.                 average.mathMax,
  161.                 worseCase.mathReverse,
  162.                 bestCase.mathReverse,
  163.                 average.mathReverse,
  164.                 worseCase.inline,
  165.                 bestCase.inline,
  166.                 average.inline,
  167.                 worseCase.@if,
  168.                 bestCase.@if,
  169.                 average.@if
  170.                 );
  171.  
  172.             WriteResults(relativeTo, worseCase, bestCase, average);
  173.  
  174.             Console.ReadLine();
  175.         }
  176.  
  177.         private static void WriteResults(double relativeTo, PerformTestResult worseCase, PerformTestResult bestCase, PerformTestResult average)
  178.         {
  179.             Console.WriteLine("max = Math.Max(max, a): {0:0.000} sec best case / {1:0.000} sec worst case / {2:0.000} sec average case", bestCase.mathMax - relativeTo, worseCase.mathMax - relativeTo, average.mathMax - relativeTo);
  180.             Console.WriteLine("max = Math.Max(a, max): {0:0.000} sec best case / {1:0.000} sec worst case / {2:0.000} sec average case", bestCase.mathReverse - relativeTo, worseCase.mathReverse - relativeTo, average.mathReverse - relativeTo);
  181.             Console.WriteLine("max = max > a ? max : a: {0:0.000} sec best case / {1:0.000} sec worst case / {2:0.000} sec average case", bestCase.inline - relativeTo, worseCase.inline - relativeTo, average.inline - relativeTo);
  182.             Console.WriteLine("if (a > max) max = a: {0:0.000} sec best case / {1:0.000} sec worst case / {2:0.000} sec average case", bestCase.@if - relativeTo, worseCase.@if - relativeTo, average.@if - relativeTo);
  183.         }
  184.  
  185.         private static double Min(params double[] values) {
  186.             var min = double.MaxValue;
  187.             for(var i = 0; i < values.Length; i++) {
  188.                 min = Math.Min(min, values[i]);
  189.             }
  190.             return min;
  191.         }
  192.  
  193.         private struct PerformTestResult
  194.         {
  195.             public double mathMax { get; set; }
  196.             public double mathReverse { get; set; }
  197.             public double inline { get; set; }
  198.             public double @if { get; set; }
  199.         }
  200.  
  201.         private static PerformTestResult PerformTests()
  202.         {
  203.             // run twice again to prime it - make sure any optimizations the processor does for code is done
  204.             ProfileMathMax();
  205.             var mathMax = ProfileMathMax();
  206.             Console.WriteLine();
  207.  
  208.             ProfileMathMaxReverse();
  209.             var mathReverse = ProfileMathMaxReverse();
  210.             Console.WriteLine();
  211.  
  212.             ProfileInline();
  213.             var inline = ProfileInline();
  214.             Console.WriteLine();
  215.  
  216.             ProfileIf();
  217.             var @if = ProfileIf();
  218.             Console.WriteLine();
  219.  
  220.             return new PerformTestResult
  221.             {
  222.                 mathMax = mathMax,
  223.                 mathReverse = mathReverse,
  224.                 inline = inline,
  225.                 @if = @if
  226.             };
  227.         }
  228.     }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement