示例#1
0
        public void Run()
        {
            if (HasRunBeenCalled())
            {
                throw new InvalidOperationException("Can only call run once.");
            }

            Console.WriteLine($"Running for {RunPeriod.TotalSeconds}sec.");

            //Write the headers, but no histograms (as we don't have any yet).
            _logWriter.Write(DateTime.Now);

            //ThreadSafe-writes require a Concurrent implementation of a Histogram
            //ThreadSafe-reads require a recorder
            var recorder = HistogramFactory
                           .With64BitBucketSize()                 //LongHistogram
                           .WithValuesFrom(1)                     //Default value
                           .WithValuesUpTo(TimeStamp.Minutes(10)) //Default value
                           .WithPrecisionOf(3)                    //Default value
                           .WithThreadSafeWrites()                //Switches internal imp to concurrent version i.e. LongConcurrentHistogram
                           .WithThreadSafeReads()                 //returns a Recorder that wraps the LongConcurrentHistogram
                           .Create();

            var outputThread = new Thread(ts => WriteToDisk((Recorder)ts));

            outputThread.Start(recorder);

            RecordMeasurements(recorder);

            //Wait for the output thread to complete writing.
            outputThread.Join();
        }
示例#2
0
        public static LongHistogram Bench(Action action, int count)
        {
            var histogram = new LongHistogram(TimeStamp.Minutes(1), 5);

            for (var i = 0; i < count; i++)
            {
                histogram.Record(() => action());
            }

            return(histogram);
        }
        public void TimeStamp_values_are_accurate()
        {
            var delay    = TimeSpan.FromSeconds(1);
            var expected = TimeStamp.Seconds(delay.Seconds);

            var start = Stopwatch.GetTimestamp();

            Thread.Sleep(delay);
            var end    = Stopwatch.GetTimestamp();
            var actual = end - start;

            Assert.AreEqual(expected, actual, expected * 0.05);
            Assert.AreEqual(TimeStamp.Seconds(60), TimeStamp.Minutes(1));
            Assert.AreEqual(TimeStamp.Minutes(60), TimeStamp.Hours(1));
        }
        public void TimeStamp_values_are_accurate()
        {
            var  delay       = TimeSpan.FromSeconds(1);
            var  expected    = TimeStamp.Seconds(delay.Seconds);
            long minAccepted = (long)(expected * 0.95);
            long maxAccepted = (long)(expected * 1.05);

            var start = Stopwatch.GetTimestamp();

            Spin.Wait(delay);
            var end    = Stopwatch.GetTimestamp();
            var actual = end - start;

            actual.Should().BeInRange(minAccepted, maxAccepted);
            Assert.Equal(TimeStamp.Seconds(60), TimeStamp.Minutes(1));
            Assert.Equal(TimeStamp.Minutes(60), TimeStamp.Hours(1));
        }
        public Recording32BitBenchmark()
        {
            const int lowestTrackableValue           = 1;
            var       highestTrackableValue          = TimeStamp.Minutes(10);
            const int numberOfSignificantValueDigits = 3;

            _testValues = TestValues(highestTrackableValue);

            _longHistogram  = new LongHistogram(highestTrackableValue, numberOfSignificantValueDigits);
            _intHistogram   = new IntHistogram(highestTrackableValue, numberOfSignificantValueDigits);
            _shortHistogram = new ShortHistogram(highestTrackableValue, numberOfSignificantValueDigits);

            _longConcurrentHistogram = new LongConcurrentHistogram(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits);
            _intConcurrentHistogram  = new IntConcurrentHistogram(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits);

            _longRecorder           = new Recorder(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits, (id, low, hi, sf) => new LongHistogram(id, low, hi, sf));
            _longConcurrentRecorder = new Recorder(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits, (id, low, hi, sf) => new LongConcurrentHistogram(id, low, hi, sf));
            _intRecorder            = new Recorder(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits, (id, low, hi, sf) => new IntHistogram(id, low, hi, sf));
            _intConcurrentRecorder  = new Recorder(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits, (id, low, hi, sf) => new IntConcurrentHistogram(id, low, hi, sf));
            _shortRecorder          = new Recorder(lowestTrackableValue, highestTrackableValue, numberOfSignificantValueDigits, (id, low, hi, sf) => new ShortHistogram(id, low, hi, sf));
        }
示例#6
0
        private static LongConcurrentHistogram RunTest(RunInfo run)
        {
            var config    = run.Configuration;
            var pool      = new RoundRobinPool(config.PoolSize, config.ProjectId);
            var histogram = new LongConcurrentHistogram(1L, TimeStamp.Minutes(10), 4);

            long documentCounter = 0;
            var  data            = new byte[config.DataSize];

            RandomNumberGenerator.Create().GetBytes(data);

            // Warm the pool up with no throttling
            SemaphoreSlim qpsThrottle = new SemaphoreSlim(config.PoolSize);

            for (int i = 0; i < config.PoolSize; i++)
            {
                WriteBatchAsync().GetAwaiter().GetResult();
            }
            // Discard the warm-up results
            histogram.Reset();

            long batchesLeft = config.Batches;
            long completed   = 0;

            var tasks = Enumerable
                        .Range(0, config.TaskCount)
                        .Select(_ => Task.Run(WriteBatchesAsync))
                        .ToArray();

            // Start tasks that we don't need to wait for at the end. (They will complete,
            // but possibly not immediately, and that's fine.)
            Task.Run(PrintDiagnosticsAsync);
            Task.Run(ReleaseThrottleAsync);

            Task.WaitAll(tasks);
            Interlocked.Increment(ref completed);
            return(histogram);

            async Task WriteBatchesAsync()
            {
                while (Interlocked.Decrement(ref batchesLeft) >= 0)
                {
                    await WriteBatchAsync();
                }
            }

            async Task WriteBatchAsync()
            {
                var db    = pool.GetFirestoreDb();
                var batch = db.StartBatch();

                for (int i = 0; i < config.BatchSize; i++)
                {
                    var documentRef = db.Collection(run.Collection).Document();
                    var document    = new SampleDocument
                    {
                        Id   = Interlocked.Increment(ref documentCounter),
                        Data = data
                    };
                    batch.Create(documentRef, document);
                }
                await qpsThrottle.WaitAsync();

                long start = Stopwatch.GetTimestamp();
                await batch.CommitAsync();

                long end = Stopwatch.GetTimestamp();

                histogram.RecordValue(Math.Max(1L, end - start));
            }

            async Task ReleaseThrottleAsync()
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                long      released  = 0;

                // Every ~50ms, see how many more batches we should release
                while (Interlocked.Read(ref completed) == 0)
                {
                    await Task.Delay(50);

                    long targetRelease = (stopwatch.ElapsedTicks * config.TargetQps) / Stopwatch.Frequency;
                    qpsThrottle.Release((int)(targetRelease - released));
                    released = targetRelease;
                }
            }

            async Task PrintDiagnosticsAsync()
            {
                while (Interlocked.Read(ref completed) == 0)
                {
                    Log($"Batches left to start: {Interlocked.Read(ref batchesLeft)}");
                    await Task.Delay(1000);
                }
            }
        }
示例#7
0
 public MetricPublisherXEventHandler()
 {
     _latencyHistogram     = new LongHistogram(TimeStamp.Minutes(1), 3);
     _conflactionHistogram = new IntHistogram(10000, 1);
 }