From 02081e6d55a1d9b8321e9297752185ede7c04a5d Mon Sep 17 00:00:00 2001 From: nkuacac Date: Wed, 11 Nov 2015 03:44:25 +0000 Subject: [PATCH] add command 95th percentile - Iteration has many steps - each step need 95th result - also add the test case for the feature Signed-off-by: zyw69542 --- cmdline/display.go | 1 + experiment/runner.go | 34 ++++++++++++++++++++++++++-------- experiment/runner_test.go | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/cmdline/display.go b/cmdline/display.go index 960c855..0799b25 100644 --- a/cmdline/display.go +++ b/cmdline/display.go @@ -32,6 +32,7 @@ func display(concurrency string, iterations int, interval int, stop int, concurr fmt.Printf("\x1b[1m%v\x1b[0m:\n", key) fmt.Printf("\x1b[1m\tCount\x1b[0m: \x1b[36m%v\x1b[0m\n", command.Count) fmt.Printf("\x1b[1m\tAverage\x1b[0m: \x1b[36m%v\x1b[0m\n", command.Average) + fmt.Printf("\x1b[1m\t95th Percentile\x1b[0m: \x1b[36m%v\x1b[0m\n", command.NinetyfifthPercentile) fmt.Printf("\x1b[1m\tLast time\x1b[0m: \x1b[36m%v\x1b[0m\n", command.LastTime) fmt.Printf("\x1b[1m\tWorst time\x1b[0m: \x1b[36m%v\x1b[0m\n", command.WorstTime) fmt.Printf("\x1b[1m\tTotal time\x1b[0m: \x1b[36m%v\x1b[0m\n", command.TotalTime) diff --git a/experiment/runner.go b/experiment/runner.go index 8fa04b5..24f2111 100644 --- a/experiment/runner.go +++ b/experiment/runner.go @@ -1,6 +1,7 @@ package experiment import ( + // "fmt" "math" "time" @@ -19,12 +20,13 @@ const ( ) type Command struct { - Count int64 - Throughput float64 - Average time.Duration - TotalTime time.Duration - LastTime time.Duration - WorstTime time.Duration + Count int64 + Throughput float64 + Average time.Duration + TotalTime time.Duration + LastTime time.Duration + WorstTime time.Duration + NinetyfifthPercentile time.Duration } type Sample struct { @@ -193,6 +195,7 @@ func (ex *SamplableExperiment) Sample() { var ninetyfifthPercentile time.Duration var percentileLength = int(math.Floor(float64(ex.maxIterations)*.05 + 0.95)) var percentile = make([]time.Duration, percentileLength, percentileLength) + var stepPercentile = make(map[string][]time.Duration) var heartbeat = time.NewTicker(1 * time.Second) startTime := time.Now() @@ -223,7 +226,8 @@ func (ex *SamplableExperiment) Sample() { ninetyfifthPercentile = percentile[percentileLength-int(math.Floor(float64(iterations)*.05+0.95))] for _, step := range iteration.Steps { - cmd := commands[step.Command] + stepindex := step.Command + cmd := commands[stepindex] cmd.Count = cmd.Count + 1 cmd.TotalTime = cmd.TotalTime + step.Duration cmd.LastTime = step.Duration @@ -233,7 +237,21 @@ func (ex *SamplableExperiment) Sample() { cmd.WorstTime = step.Duration } - commands[step.Command] = cmd + stepPercent := stepPercentile[stepindex] + if len(stepPercent) == 0 { + stepPercent = make([]time.Duration, percentileLength, percentileLength) + } + if step.Duration > stepPercent[0] { + stepPercent[0] = step.Duration + for i := 0; i < percentileLength-1 && step.Duration > stepPercent[i+1]; i++ { + stepPercent[i] = stepPercent[i+1] + stepPercent[i+1] = step.Duration + } + } + + stepPercentile[stepindex] = stepPercent + cmd.NinetyfifthPercentile = stepPercentile[stepindex][percentileLength-int(math.Floor(float64(iterations)*.05+0.95))] + commands[stepindex] = cmd } if iteration.Error != nil { diff --git a/experiment/runner_test.go b/experiment/runner_test.go index c505ab5..b59e22b 100644 --- a/experiment/runner_test.go +++ b/experiment/runner_test.go @@ -287,6 +287,29 @@ var _ = Describe("ExperimentConfiguration and Sampler", func() { Ω((<-samples).NinetyfifthPercentile).Should(Equal(time.Duration(expectedPercentiles[q]) * time.Second)) } }) + + It("Calculates the 95th percentile for command", func() { + samplesToSend := []int{2, 5, 1, 9, 12, 8, 19, 57, 33, 44, 1, 12, 43, 99, 98, 19, 34, 19, 7, 55, 23} + expectedPercentiles := []int{2, 5, 5, 9, 12, 12, 19, 57, 57, 57, 57, 57, 57, 99, 99, 99, 99, 99, 99, 99, 98} + + go func() { + for i := 0; i < maxIterations; i++ { + iteration <- IterationResult{0, + []StepResult{ + StepResult{Command: "push", Duration: time.Duration(samplesToSend[i]) * time.Second}, + StepResult{Command: "list", Duration: time.Duration(samplesToSend[i]) * time.Second}, + }, + nil} + } + }() + + for q := 0; q < maxIterations; q++ { + sample := <-samples + Ω(sample.Commands["push"].NinetyfifthPercentile).Should(Equal(time.Duration(expectedPercentiles[q]) * time.Second)) + Ω(sample.Commands["list"].NinetyfifthPercentile).Should(Equal(time.Duration(expectedPercentiles[q]) * time.Second)) + } + }) + }) Describe("Scheduling", func() {