// Runs a single benchmark for at least a second and computes the
        // average time it takes to run a single iteration.
        public void RunSingleBenchmark(Benchmark benchmark)
        {
            bool doWarmup        = benchmark.doWarmup;
            bool doDeterministic = benchmark.doDeterministic;

            // Sets up data in order to skip or not the warmup phase.
            BenchmarkRunData data = new BenchmarkRunData(0, 0);

            if (doWarmup)
            {
                Measure(data, doDeterministic);
                data = new BenchmarkRunData(0, 0);
            }
            while (data.runs < benchmark.minIterations)
            {
                Measure(data, doDeterministic);
            }
            long usec = (data.elapsed * 1000) / data.runs;

            this.NotifyStep(new BenchmarkResult(benchmark, usec));
        }
        public void Measure(BenchmarkRunData data, bool doDeterministic)
        {
            long      elapsed = 0;
            Stopwatch sw      = new Stopwatch();

            // Run either for 1 second or for the number of iterations specified
            // by minIterations, depending on the config flag doDeterministic.
            sw.Start();
            int runs = 0;

            for (int i = 0; (doDeterministic ?
                             i < benchmark.deterministicIterations : elapsed < 1000); i++)
            {
                benchmark.run();
                elapsed = sw.ElapsedMilliseconds;
                runs++;
            }
            if (data != null)
            {
                data.runs    += runs;
                data.elapsed += elapsed;
            }
        }