1// Copyright (c) 2015-2021 MinIO, Inc. 2// 3// This file is part of MinIO Object Storage stack 4// 5// This program is free software: you can redistribute it and/or modify 6// it under the terms of the GNU Affero General Public License as published by 7// the Free Software Foundation, either version 3 of the License, or 8// (at your option) any later version. 9// 10// This program is distributed in the hope that it will be useful 11// but WITHOUT ANY WARRANTY; without even the implied warranty of 12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13// GNU Affero General Public License for more details. 14// 15// You should have received a copy of the GNU Affero General Public License 16// along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18package net 19 20import ( 21 "github.com/minio/madmin-go" 22 "github.com/montanaflynn/stats" 23) 24 25// ComputePerfStats takes arrays of Latency & Throughput to compute Statistics 26func ComputePerfStats(latencies, throughputs []float64) (madmin.NetLatency, madmin.NetThroughput, error) { 27 var avgLatency float64 28 var percentile50Latency float64 29 var percentile90Latency float64 30 var percentile99Latency float64 31 var minLatency float64 32 var maxLatency float64 33 34 var avgThroughput float64 35 var percentile50Throughput float64 36 var percentile90Throughput float64 37 var percentile99Throughput float64 38 var minThroughput float64 39 var maxThroughput float64 40 var err error 41 42 if avgLatency, err = stats.Mean(latencies); err != nil { 43 return madmin.NetLatency{}, madmin.NetThroughput{}, err 44 } 45 if percentile50Latency, err = stats.Percentile(latencies, 50); err != nil { 46 return madmin.NetLatency{}, madmin.NetThroughput{}, err 47 } 48 if percentile90Latency, err = stats.Percentile(latencies, 90); err != nil { 49 return madmin.NetLatency{}, madmin.NetThroughput{}, err 50 } 51 if percentile99Latency, err = stats.Percentile(latencies, 99); err != nil { 52 return madmin.NetLatency{}, madmin.NetThroughput{}, err 53 } 54 if maxLatency, err = stats.Max(latencies); err != nil { 55 return madmin.NetLatency{}, madmin.NetThroughput{}, err 56 } 57 if minLatency, err = stats.Min(latencies); err != nil { 58 return madmin.NetLatency{}, madmin.NetThroughput{}, err 59 } 60 l := madmin.NetLatency{ 61 Avg: avgLatency, 62 Percentile50: percentile50Latency, 63 Percentile90: percentile90Latency, 64 Percentile99: percentile99Latency, 65 Min: minLatency, 66 Max: maxLatency, 67 } 68 69 if avgThroughput, err = stats.Mean(throughputs); err != nil { 70 return madmin.NetLatency{}, madmin.NetThroughput{}, err 71 } 72 if percentile50Throughput, err = stats.Percentile(throughputs, 50); err != nil { 73 return madmin.NetLatency{}, madmin.NetThroughput{}, err 74 } 75 if percentile90Throughput, err = stats.Percentile(throughputs, 90); err != nil { 76 return madmin.NetLatency{}, madmin.NetThroughput{}, err 77 } 78 if percentile99Throughput, err = stats.Percentile(throughputs, 99); err != nil { 79 return madmin.NetLatency{}, madmin.NetThroughput{}, err 80 } 81 if maxThroughput, err = stats.Max(throughputs); err != nil { 82 return madmin.NetLatency{}, madmin.NetThroughput{}, err 83 } 84 if minThroughput, err = stats.Min(throughputs); err != nil { 85 return madmin.NetLatency{}, madmin.NetThroughput{}, err 86 } 87 t := madmin.NetThroughput{ 88 Avg: avgThroughput, 89 Percentile50: percentile50Throughput, 90 Percentile90: percentile90Throughput, 91 Percentile99: percentile99Throughput, 92 Min: minThroughput, 93 Max: maxThroughput, 94 } 95 96 return l, t, nil 97} 98