/// <summary> /// Для проведения тестов с множеством предопределенных аргументов. /// </summary> /// <param name="arguments"></param> /// <param name="idleRun"></param> /// <returns></returns> public double TestProcedure(IEnumerable <T> arguments, bool idleRun = true) { Contract.Requires <ArgumentNullException>(arguments != null, "arguments"); Contract.Requires <ArgumentException>(arguments.Count() > 0, "The argument list should not be empty."); int testCount = 0; if (idleRun) { this.TestedProcedure(arguments.First()); } NanoStopWatch sw = new NanoStopWatch(); sw.start(); foreach (T nextArgument in arguments) { this.TestedProcedure(nextArgument); ++testCount; } sw.stop(); return((double)(sw.getIntervalInMillis() / testCount)); }
/// <summary> /// Для проведения нескольких тестов с одним аргументом. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="argument"></param> /// <param name="stopCriteria"></param> /// <param name="idleRun"></param> /// <returns></returns> public double TestProcedure(T argument, Func <int, bool> stopCriteria, bool idleRun = true) { int testCount = 0; if (idleRun) { this.TestedProcedure(argument); stopCriteria(0); } NanoStopWatch sw = new NanoStopWatch(); sw.start(); while (!stopCriteria(testCount)) { this.TestedProcedure(argument); ++testCount; } sw.stop(); return((double)(sw.getIntervalInMillis() / testCount)); }
/// <summary> /// Performs a performance test of specified procedure by substituting different /// values of its argument and returning a mean value of function performance time. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="procedure"></param> /// <param name="initialArgument"></param> /// <param name="changeFunction"></param> /// <param name="stopCriteria"></param> /// <param name="precalculateArguments"></param> /// <param name="idleRun"></param> /// <returns></returns> public double TestProcedure( T initialArgument, Func <int, T, T> changeFunction, Func <int, T, bool> stopCriteria, bool precalculateArguments = true, bool idleRun = true) { Contract.Requires <ArgumentNullException>(changeFunction != null, "changeFunction"); Contract.Requires <ArgumentNullException>(stopCriteria != null, "stopCriteria"); int totalChanges = 0; NanoStopWatch sw = new NanoStopWatch(); T currentArgument = initialArgument; List <KeyValuePair <T, double> > result = new List <KeyValuePair <T, double> >(); if (precalculateArguments) { List <T> preparedArguments = new List <T>(); preparedArguments.Add(initialArgument); while (!stopCriteria(totalChanges, currentArgument)) { currentArgument = changeFunction(totalChanges, currentArgument); preparedArguments.Add(currentArgument); ++totalChanges; } // Фактически мы выполнили предвычисление всех значений аргумента, // так что теперь выполняется вызов перегруженного варианта функции. return(TestProcedure(preparedArguments, idleRun)); } if (idleRun) { this.TestedProcedure(currentArgument); stopCriteria(0, currentArgument); changeFunction(0, currentArgument); } sw.reset(); sw.start(); while (!stopCriteria(totalChanges, currentArgument)) { // make time measurements // ----------------------- this.TestedProcedure(currentArgument); currentArgument = changeFunction(totalChanges, currentArgument); ++totalChanges; } sw.stop(); return((double)sw.getIntervalInMillis() / totalChanges); }