Esempio n. 1
0
        private int FindIterationCount(StopwatchTimer timer, Action method, long minTicksForMeasurement,
                                       Action <string> log)
        {
            var iterationCount = 1;
            var diff           = Measurer.MeasureDiffOutsideLoop(timer, new DelegateAction(method), iterationCount);

            while (diff < minTicksForMeasurement || diff > minTicksForMeasurement * 2)
            {
                iterationCount = (int)((iterationCount * minTicksForMeasurement) / Math.Max(diff, 1));
                diff           = Measurer.MeasureDiffOutsideLoop(timer, new DelegateAction(method), iterationCount);
                log?.Invoke($"Diff {diff} IterationCount {iterationCount}");
            }

            return(iterationCount);
        }
Esempio n. 2
0
        public QuickPerfMeasurements Run(Action <string> log)//<T>(this QuickPerfConfig<T> config)
        {
            Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
            Thread.CurrentThread.Priority = ThreadPriority.Highest;

            var timer     = new StopwatchTimer();
            var timerSpec = timer.Spec;
            Func <double, double> toNs = ticks => 1000 * 1000 * 1000 * ticks / (double)timerSpec.Frequency;

            const int MinTicksExtraMultiplier = 40;
            const int PrecisionDigits         = 3;
            int       precisionMultiplier     = 1;

            for (int i = 0; i < PrecisionDigits; i++)
            {
                precisionMultiplier *= 10;
            }
            const int precisionMeasurementCount          = 11;
            const int measurementsPerParamPerMethodCount = 21;

            // Measure timer precision
            var precisionMeasurements = ReserveMeasurements(precisionMeasurementCount);

            TimerMeasurer.MeasurePrecision(timer, precisionMeasurements);
            precisionMeasurements.Sort();
            var min    = precisionMeasurements.First();
            var median = precisionMeasurements.Middle();
            var max    = precisionMeasurements.Last();

            log?.Invoke($"Precision {min} - {median} - {max} ticks");

            var minTicksForMeasurement = median * precisionMultiplier * MinTicksExtraMultiplier;

            foreach (var param in m_params)
            {
                // TODO: When to do
                m_setup?.Invoke(param);

                foreach (var namedMethod in m_methods)
                {
                    var method       = namedMethod.Method;
                    var methodAction = new DelegateAction(method);
                    var idleAction   = new DelegateAction(IdleAction);
                    // Pre-JIT and warmup
                    var warmupIdleTime = Measurer.MeasureDiffOutsideLoop(timer, idleAction, 3);
                    var warmupTime     = Measurer.MeasureDiffOutsideLoop(timer, methodAction, 3);

                    ForceAndWaitForGarbageCollection();
                    var iterationCount = FindIterationCount(timer, method, minTicksForMeasurement, log);

                    //ForceAndWaitForGarbageCollection();
                    var idleTime = Measurer.MeasureDiffOutsideLoop(timer, idleAction, iterationCount);
                    log?.Invoke($"Idle Ticks: {idleTime} ns: {toNs(idleTime / (double)iterationCount)}");

                    var measurements = ReserveMeasurements(measurementsPerParamPerMethodCount);
                    ForceAndWaitForGarbageCollection();
                    for (int i = 0; i < measurements.Count; i++)
                    {
                        //ForceAndWaitForGarbageCollection();
                        var methodTime = Measurer.MeasureDiffOutsideLoop(timer, methodAction, iterationCount);
                        measurements.Set(i, methodTime);
                        log?.Invoke($"{namedMethod.Name} Ticks: {methodTime} ns: {toNs(methodTime / (double)iterationCount)}");
                    }
                }
            }
            return(new QuickPerfMeasurements());
        }