/// <summary>
        /// each objClass each gets numOfClasses number of structs
        /// </summary>
        public heavyClass[] getMultiCallerClasses(int numOfClasses, int numOfCallers)
        {
            var o = new objClass();

            var a = new heavyClass[numOfClasses * numOfCallers];
            int count = 0;
            for (int i = 0; i < numOfCallers; i++)
            {
                var ia = o.getClasses(numOfClasses);
                foreach (var c in ia)
                {
                    a[count++] = c;
                }
            }

            return a;
        }
        /// <summary>
        /// each objClass each gets numOfStructs number of structs
        /// </summary>
        public heavyStruct[] getMultiCallerStructs(int numOfStructs, int numOfCallers)
        {
            var o = new objClass();

            var a = new heavyStruct[numOfStructs * numOfCallers];
            int count = 0;
            for (int i = 0; i < numOfCallers; i++)
            {
                var ia = o.getStructs(numOfStructs);
                foreach (var s in ia)
                {
                    a[count++] = s;
                }
            }

            return a;
        }
        public void compare(int times)
        {
            int x = 10000;
            int y = 100;
            var b = new builder();
            var o = new objClass();

            var a = new double[times];
            var mem = new List<long>(times);

            Stopwatch s = new Stopwatch();

            Console.WriteLine("Working...");

            for (int j = 0; j < 6; j++)
            {
                GC.WaitForFullGCComplete();
                switch (j)
                {
                    case 0:
                        Console.WriteLine("Structs...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            o.getStructs(x * 100);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    case 1:
                        Console.WriteLine("Classes...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            o.getClasses(x * 100);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    case 2:
                        Console.WriteLine("Structs + concat...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            b.getMultiCallerStructs(x,y);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    case 3:
                        Console.WriteLine("Classes + concat...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            b.getMultiCallerClasses(x,y);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    case 4:
                        Console.WriteLine("Structs + Recursive + concat...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            b.getStructRecursive(10, x, y);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    case 5:
                        Console.WriteLine("Classes + Recursive + concat...");
                        for (int i = 0; i < times; i++)
                        {
                            s.Start();
                            b.getClassRecursive(10, x, y);
                            s.Stop();
                            a[i] = s.Elapsed.TotalMilliseconds;
                            s.Reset();
                            mem.Add(GC.GetTotalMemory(false));
                        }
                        break;
                    default:
                        Console.WriteLine("huh?");
                        break;
                }

                double max = a.Max();
                Console.WriteLine("Max: {0}", max);

                double min = a.Min();
                Console.WriteLine("Min: {0}", min);

                double mean = a.Average();
                Console.WriteLine("Mean: {0}", mean);

                var deviations = new double[a.Length];
                for (int i = 0; i < a.Length; i++)
                {
                    deviations[i] = Math.Pow((a[i] - mean), 2.0);
                }

                double averageVariance = deviations.Average();
                Console.WriteLine("Variance: {0}", averageVariance);

                //The higher this is, the more GC spikes we had
                double standardDeviation = Math.Sqrt(averageVariance);
                Console.WriteLine("Population Standard Deviation: {0}", standardDeviation);

                var adjusted = new List<double>();

                for (int i = 0; i < a.Length; i++)
                {
                    if (deviations[i] < averageVariance)
                    {
                        adjusted.Add(a[i]);
                    }
                }

                //This is to remove the spikes from GC
                var adjustedMean = adjusted.Average();
                Console.WriteLine("Adjusted Mean: {0}", adjustedMean);

                var avgMem = mem.Average();
                Console.WriteLine("Average Memory: {0}", avgMem/1000000.0);
                Console.WriteLine();
                mem.Clear();
            }
        }