Skip to content

Commit 0ee6b14

Browse files
committed
Correcting usage of Stopwatch TimeStamp Ticks vs DateTime Ticks
1 parent f5a88d0 commit 0ee6b14

11 files changed

Lines changed: 127 additions & 95 deletions

File tree

README.md

Lines changed: 66 additions & 58 deletions
Large diffs are not rendered by default.

src/HdrHistogram.Examples/SimpleHistogramExample.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace HdrHistogram.Examples
2020
/// </summary>
2121
static class SimpleHistogramExample
2222
{
23-
private static readonly LongHistogram Histogram = new LongHistogram(TimeSpan.TicksPerHour, 3);
23+
private static readonly LongHistogram Histogram = new LongHistogram(TimeStamp.Hours(1), 3);
2424
private static volatile Socket _socket;
2525
private static readonly Lazy<AddressFamily> AddressFamily = new Lazy<AddressFamily>(() => GetAddressFamily("google.com"));
2626

@@ -57,20 +57,20 @@ private static void OutputMeasurements()
5757
var size = Histogram.GetEstimatedFootprintInBytes();
5858
Console.WriteLine("Histogram size = {0} bytes ({1:F2} MB)", size, size / 1024.0 / 1024.0);
5959

60-
Console.WriteLine("Recorded latencies [in ticks] for Create+Close of a DatagramSocket:");
60+
Console.WriteLine("Recorded latencies [in system clock ticks] for Create+Close of a DatagramSocket:");
6161
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.None);
6262
Console.WriteLine();
6363

6464
Console.WriteLine("Recorded latencies [in usec] for Create+Close of a DatagramSocket:");
65-
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TicksToMicroseconds);
65+
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TimeStampToMicroseconds);
6666
Console.WriteLine();
6767

6868
Console.WriteLine("Recorded latencies [in msec] for Create+Close of a DatagramSocket:");
69-
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TicksToMilliseconds);
69+
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TimeStampToMilliseconds);
7070
Console.WriteLine();
7171

7272
Console.WriteLine("Recorded latencies [in sec] for Create+Close of a DatagramSocket:");
73-
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TicksToSeconds);
73+
Histogram.OutputPercentileDistribution(Console.Out, outputValueUnitScalingRatio: OutputScalingFactor.TimeStampToSeconds);
7474
}
7575

7676
private static void CreateAndCloseDatagramSocket()

src/HdrHistogram.UnitTests/HgrmPercentileDistrubutionOutputTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
using System;
2-
using System.Globalization;
1+
using System.Globalization;
32
using System.IO;
43
using NUnit.Framework;
54

65
namespace HdrHistogram.UnitTests
76
{
7+
/// <summary>
8+
/// Validates against files generated by the official Java implementation.
9+
/// </summary>
810
[TestFixture]
911
public sealed class HgrmPercentileDistrubutionOutputTests
1012
{
1113
[Test, Combinatorial]
1214
public void PercentileDistrubution_hgrm_output_is_in_correct_format(
13-
[Values(TimeSpan.TicksPerHour)]long highestTrackableValue,
15+
[Values(36000000000)]long highestTrackableValue,
1416
[Values(1, 2, 3, 4, 5)]int signigicantDigits,
1517
[Values(10000.0)]double scaling,
1618
[Values(5, 10, 20)]int percentileTicksPerHalfDistance)
@@ -31,7 +33,7 @@ public void PercentileDistrubution_hgrm_output_is_in_correct_format(
3133

3234
[Test, Combinatorial]
3335
public void PercentileDistrubution_csv_output_is_in_correct_format(
34-
[Values(TimeSpan.TicksPerHour)]long highestTrackableValue,
36+
[Values(36000000000)]long highestTrackableValue,
3537
[Values(1, 2, 3, 4, 5)]int signigicantDigits,
3638
[Values(10000.0)]double scaling,
3739
[Values(5, 10, 20)]int percentileTicksPerHalfDistance)

src/HdrHistogram.UnitTests/HistogramTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace HdrHistogram.UnitTests
55
{
66
public abstract class HistogramTestBase
77
{
8-
private const long HighestTrackableValue = TimeSpan.TicksPerHour; // e.g. for 1 hr in ticks
8+
private const long HighestTrackableValue = 7716549600;//TimeStamp.Hours(1); // e.g. for 1 hr in system clock ticks (StopWatch.Frequency)
99
private const int NumberOfSignificantValueDigits = 3;
1010
private const long TestValueLevel = 4;
1111

src/HdrHistogram/HistogramBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace HdrHistogram
2828
/// 36,000,000,000 while maintaining a value precision of 3 significant digits across that range.
2929
/// Value quantization within the range will thus be no larger than 1/1,000th (or 0.1%) of any value.
3030
/// This example Histogram could be used to track and analyze the counts of observed response times ranging between
31-
/// 1 tick (100 nanoseconds) and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
31+
/// 100 nanoseconds and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
3232
/// 100 microseconds, a resolution of 1 millisecond(or better) up to one second, and a resolution of 1 second
3333
/// (or better) up to 1,000 seconds.
3434
/// At it's maximum tracked value(1 hour), it would still maintain a resolution of 3.6 seconds (or better).
@@ -122,8 +122,8 @@ public abstract class HistogramBase
122122
/// <remarks>
123123
/// Providing a lowestTrackableValue is useful in situations where the units used for the histogram's values are much
124124
/// smaller that the minimal accuracy required.
125-
/// For example when tracking time values stated in ticks (100 nanoseconds), where the minimal accuracy required is a
126-
/// microsecond, the proper value for lowestTrackableValue would be 10.
125+
/// For example when tracking time values stated in nanoseconds, where the minimal accuracy required is a
126+
/// microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 1000.
127127
/// </remarks>
128128
protected HistogramBase(long lowestTrackableValue, long highestTrackableValue, int numberOfSignificantValueDigits)
129129
{

src/HdrHistogram/HistogramExtensions.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public static IEnumerable<HistogramIterationValue> Percentiles(this HistogramBas
111111
public static void OutputPercentileDistribution(this HistogramBase histogram,
112112
TextWriter writer,
113113
int percentileTicksPerHalfDistance = 5,
114-
double outputValueUnitScalingRatio = OutputScalingFactor.TicksToMilliseconds,
114+
double outputValueUnitScalingRatio = OutputScalingFactor.None,
115115
bool useCsvFormat = false)
116116
{
117117
var formatter = useCsvFormat
@@ -144,17 +144,22 @@ public static void OutputPercentileDistribution(this HistogramBase histogram,
144144

145145
/// <summary>
146146
/// Executes the action and records the time to complete the action.
147-
/// The time is recorded in ticks.
147+
/// The time is recorded in system clock ticks.
148+
/// This time may vary between frameworks and platforms, but is equivalent to <c>(1/Stopwatch.Frequency)</c> seconds.
148149
/// Note this is a convenience method and can carry a cost.
149150
/// If the <paramref name="action"/> delegate is not cached, then it may incur an allocation cost for each invocation of <see cref="Record"/>
150151
/// </summary>
151152
/// <param name="histogram">The Histogram to record the latency in.</param>
152153
/// <param name="action">The functionality to execute and measure</param>
153154
/// <remarks>
154155
/// <para>
155-
/// Ticks are used as the unit of recording here as they are the smallest unit that .NET can measure
156-
/// and require no conversion at time of recording. Instead conversion (scaling) can be done at time
157-
/// of output to microseconds, milliseconds, seconds or other appropriate unit.
156+
/// The units returned from <code>Stopwatch.GetTimestamp()</code> are used as the unit of
157+
/// recording here as they are the smallest unit that .NET can measure and require no
158+
/// conversion at time of recording.
159+
/// Instead conversion (scaling) can be done at time of output to microseconds, milliseconds,
160+
/// seconds or other appropriate unit.
161+
/// These units are sometimes refered to as ticks, but should not not to be confused with
162+
/// ticks used in <seealso cref="DateTime"/> or <seealso cref="TimeSpan"/>.
158163
/// </para>
159164
/// <para>
160165
/// If you are able to cache the <paramref name="action"/> delegate, then doing so is encouraged.
@@ -187,9 +192,8 @@ public static void Record(this HistogramBase histogram, Action action)
187192
{
188193
var start = Stopwatch.GetTimestamp();
189194
action();
190-
var elapsedTicks = (Stopwatch.GetTimestamp() - start);
191-
histogram.RecordValue(elapsedTicks);
195+
var elapsed = Stopwatch.GetTimestamp() - start;
196+
histogram.RecordValue(elapsed);
192197
}
193198
}
194-
195199
}

src/HdrHistogram/IntHistogram.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace HdrHistogram
2323
/// 36,000,000,000 while maintaining a value precision of 3 significant digits across that range.
2424
/// Value quantization within the range will thus be no larger than 1/1,000th (or 0.1%) of any value.
2525
/// This example Histogram could be used to track and analyze the counts of observed response times ranging between
26-
/// 1 tick (100 nanoseconds) and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
26+
/// 100 nanoseconds and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
2727
/// 100 microseconds, a resolution of 1 millisecond(or better) up to one second, and a resolution of 1 second
2828
/// (or better) up to 1,000 seconds.
2929
/// At it's maximum tracked value(1 hour), it would still maintain a resolution of 3.6 seconds (or better).
@@ -52,7 +52,7 @@ public IntHistogram(long highestTrackableValue, int numberOfSignificantValueDigi
5252
/// <summary>
5353
/// Construct a <see cref="IntHistogram"/> given the lowest and highest values to be tracked and a number of significant decimal digits.
5454
/// Providing a <paramref name="lowestTrackableValue"/> is useful is situations where the units used for the histogram's values are much smaller that the minimal accuracy required.
55-
/// For example when tracking time values stated in ticks (100 nanosecond units), where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 10.
55+
/// For example when tracking time values stated in nanoseconds, where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 1000.
5656
/// </summary>
5757
/// <param name="lowestTrackableValue">
5858
/// The lowest value that can be tracked (distinguished from 0) by the histogram.

src/HdrHistogram/LongHistogram.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace HdrHistogram
2323
/// 36,000,000,000 while maintaining a value precision of 3 significant digits across that range.
2424
/// Value quantization within the range will thus be no larger than 1/1,000th (or 0.1%) of any value.
2525
/// This example Histogram could be used to track and analyze the counts of observed response times ranging between
26-
/// 1 tick (100 nanoseconds) and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
26+
/// 100 nanoseconds and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
2727
/// 100 microseconds, a resolution of 1 millisecond(or better) up to one second, and a resolution of 1 second
2828
/// (or better) up to 1,000 seconds.
2929
/// At it's maximum tracked value(1 hour), it would still maintain a resolution of 3.6 seconds (or better).
@@ -51,7 +51,7 @@ public LongHistogram(long highestTrackableValue, int numberOfSignificantValueDig
5151
/// <summary>
5252
/// Construct a <see cref="LongHistogram"/> given the lowest and highest values to be tracked and a number of significant decimal digits.
5353
/// Providing a <paramref name="lowestTrackableValue"/> is useful is situations where the units used for the histogram's values are much smaller that the minimal accuracy required.
54-
/// For example when tracking time values stated in tick (100 nanosecond units), where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 10.
54+
/// For example when tracking time values stated in nanosecond units, where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 1000.
5555
/// </summary>
5656
/// <param name="lowestTrackableValue">
5757
/// The lowest value that can be tracked (distinguished from 0) by the histogram.

src/HdrHistogram/OutputScalingFactor.cs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* http://creativecommons.org/publicdomain/zero/1.0/
77
*/
88

9-
using System;
9+
using System.Diagnostics;
1010

1111
namespace HdrHistogram
1212
{
@@ -16,23 +16,40 @@ namespace HdrHistogram
1616
public static class OutputScalingFactor
1717
{
1818
/// <summary>
19-
/// For use when values are recorded in ticks and output should be in ticks
19+
/// For use when values are recorded and reported in the same unit of measurement.
2020
/// </summary>
2121
public const double None = 1.0;
22-
22+
2323
/// <summary>
24-
/// For use when values are recorded in ticks and output should be measured in microseconds.
24+
/// For use when values are recorded with <seealso cref="Stopwatch.GetTimestamp()"/> and output should be reported in microseconds.
2525
/// </summary>
26-
public const double TicksToMicroseconds = 10.0;
26+
public static readonly double TimeStampToMicroseconds = Stopwatch.Frequency / (1000d * 1000d);
2727

2828
/// <summary>
29-
/// For use when values are recorded in ticks and output should be measured in milliseconds.
29+
/// For use when values are recorded with <seealso cref="Stopwatch.GetTimestamp()"/> and output should be reported in milliseconds.
3030
/// </summary>
31-
public const double TicksToMilliseconds = TimeSpan.TicksPerMillisecond;
31+
public static readonly double TimeStampToMilliseconds = Stopwatch.Frequency / 1000d;
3232

3333
/// <summary>
34-
/// For use when values are recorded in ticks and output should be measured in seconds.
34+
/// For use when values are recorded with <seealso cref="Stopwatch.GetTimestamp()"/> and output should be reported in seconds.
3535
/// </summary>
36-
public const double TicksToSeconds = TimeSpan.TicksPerSecond;
36+
public static readonly double TimeStampToSeconds = Stopwatch.Frequency;
37+
}
38+
39+
public static class TimeStamp
40+
{
41+
public static long Seconds(int seconds)
42+
{
43+
return Stopwatch.Frequency*seconds;
44+
}
45+
46+
public static long Minutes(int minutes)
47+
{
48+
return Stopwatch.Frequency * minutes * 60L;
49+
}
50+
public static long Hours(int hours)
51+
{
52+
return Stopwatch.Frequency * hours * 60L * 60L;
53+
}
3754
}
3855
}

src/HdrHistogram/ShortHistogram.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace HdrHistogram
2424
/// 36,000,000,000 while maintaining a value precision of 3 significant digits across that range.
2525
/// Value quantization within the range will thus be no larger than 1/1,000th (or 0.1%) of any value.
2626
/// This example Histogram could be used to track and analyze the counts of observed response times ranging between
27-
/// 1 tick (100 nanoseconds) and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
27+
/// 100 nanoseconds and 1 hour in magnitude, while maintaining a value resolution of 100 nanosecond up to
2828
/// 100 microseconds, a resolution of 1 millisecond(or better) up to one second, and a resolution of 1 second
2929
/// (or better) up to 1,000 seconds.
3030
/// At it's maximum tracked value(1 hour), it would still maintain a resolution of 3.6 seconds (or better).
@@ -53,7 +53,7 @@ public ShortHistogram(long highestTrackableValue, int numberOfSignificantValueDi
5353
/// <summary>
5454
/// Construct a <see cref="ShortHistogram"/> given the lowest and highest values to be tracked and a number of significant decimal digits.
5555
/// Providing a <paramref name="lowestTrackableValue"/> is useful is situations where the units used for the histogram's values are much smaller that the minimal accuracy required.
56-
/// For example when tracking time values stated in ticks (100 nanosecond units), where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 10.
56+
/// For example when tracking time values stated in nanoseconds, where the minimal accuracy required is a microsecond, the proper value for <paramref name="lowestTrackableValue"/> would be 1000.
5757
/// </summary>
5858
/// <param name="lowestTrackableValue">
5959
/// The lowest value that can be tracked (distinguished from 0) by the histogram.

0 commit comments

Comments
 (0)