From b65e0e2406adafe0b08338d54b48e5a40d920ff0 Mon Sep 17 00:00:00 2001 From: Coda Hale Date: Thu, 16 Jul 2020 14:30:17 -0600 Subject: [PATCH] Use proper types for measurements. --- cmd/usl/usl.go | 4 ++-- cmd/usl/usl_test.go | 2 -- measurement.go | 33 ++++++++++++++++++--------------- measurement_test.go | 5 +++-- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/cmd/usl/usl.go b/cmd/usl/usl.go index c430d97..ec47b3f 100644 --- a/cmd/usl/usl.go +++ b/cmd/usl/usl.go @@ -196,12 +196,12 @@ func parseCSV(filename string, nCol, rCol int, skipHeaders bool) ([]usl.Measurem } //nolint:goerr113 // not a package -func parseLine(i, nCol, xCol int, line []string) (float64, float64, error) { +func parseLine(i, nCol, xCol int, line []string) (uint64, float64, error) { if len(line) != 2 { return 0, 0, fmt.Errorf("invalid line at line %d", i+1) } - n, err := strconv.ParseFloat(line[nCol-1], 64) + n, err := strconv.ParseUint(line[nCol-1], 10, 64) if err != nil { return 0, 0, fmt.Errorf("error at line %d, column %d: %w", i+1, nCol, err) } diff --git a/cmd/usl/usl_test.go b/cmd/usl/usl_test.go index 67bc478..10c3543 100644 --- a/cmd/usl/usl_test.go +++ b/cmd/usl/usl_test.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "io/ioutil" "os" "testing" @@ -62,7 +61,6 @@ func TestMainRun(t *testing.T) { `, string(stdout)) - fmt.Println(string(stderr)) assert.Equal(t, "stderr", `URL parameters: σ=0.02772985648395876, κ=0.00010434289088915312, λ=89.98778453648904 max throughput: 1883.7622524836281, max concurrency: 96 diff --git a/measurement.go b/measurement.go index 8a05b83..4d010c3 100644 --- a/measurement.go +++ b/measurement.go @@ -1,13 +1,16 @@ package usl -import "fmt" +import ( + "fmt" + "time" +) // Measurement is a simultaneous measurement of at least two of the parameters of Little's Law: // concurrency, throughput, and latency. The third parameter is inferred from the other two. type Measurement struct { Concurrency float64 // The average number of concurrent events. - Throughput float64 // The long-term average arrival rate of events. - Latency float64 // The average duration of events. + Throughput float64 // The long-term average arrival rate of events, in events/sec. + Latency float64 // The average duration of events in seconds. } func (m *Measurement) String() string { @@ -16,30 +19,30 @@ func (m *Measurement) String() string { // ConcurrencyAndLatency returns a measurement of a system's latency at a given level of // concurrency. The throughput of the system is derived via Little's Law. -func ConcurrencyAndLatency(n, r float64) Measurement { +func ConcurrencyAndLatency(n uint64, r time.Duration) Measurement { return Measurement{ - Concurrency: n, // L - Throughput: n / r, // λ=L/W - Latency: r, // W + Concurrency: float64(n), // L + Throughput: float64(n) / r.Seconds(), // λ=L/W + Latency: r.Seconds(), // W } } // ConcurrencyAndThroughput returns a measurement of a system's throughput at a given level of // concurrency. The latency of the system is derived via Little's Law. -func ConcurrencyAndThroughput(n, x float64) Measurement { +func ConcurrencyAndThroughput(n uint64, x float64) Measurement { return Measurement{ - Concurrency: n, // L - Throughput: x, // λ - Latency: n / x, // W=L/λ + Concurrency: float64(n), // L + Throughput: x, // λ + Latency: float64(n) / x, // W=L/λ } } // ThroughputAndLatency returns a measurement of a system's latency at a given level of throughput. // The concurrency of the system is derived via Little's Law. -func ThroughputAndLatency(x, r float64) Measurement { +func ThroughputAndLatency(x float64, r time.Duration) Measurement { return Measurement{ - Concurrency: x * r, // L=λW - Throughput: x, // λ - Latency: r, // W + Concurrency: x * r.Seconds(), // L=λW + Throughput: x, // λ + Latency: r.Seconds(), // W } } diff --git a/measurement_test.go b/measurement_test.go index 6168c95..597281a 100644 --- a/measurement_test.go +++ b/measurement_test.go @@ -2,6 +2,7 @@ package usl import ( "testing" + "time" "github.com/codahale/usl/internal/assert" ) @@ -13,7 +14,7 @@ func TestMeasurement_String(t *testing.T) { } func TestConcurrencyAndLatency(t *testing.T) { - m := ConcurrencyAndLatency(3, 0.6) + m := ConcurrencyAndLatency(3, 600*time.Millisecond) assert.Equal(t, "Concurrency", 3.0, m.Concurrency, epsilon) assert.Equal(t, "Latency", 0.6, m.Latency, epsilon) @@ -29,7 +30,7 @@ func TestConcurrencyAndThroughput(t *testing.T) { } func TestThroughputAndLatency(t *testing.T) { - m := ThroughputAndLatency(5, 0.6) + m := ThroughputAndLatency(5, 600*time.Millisecond) assert.Equal(t, "Concurrency", 3.0, m.Concurrency, epsilon) assert.Equal(t, "Latency", 0.6, m.Latency, epsilon)