1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef Stats_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define Stats_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm> 12*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkFloatingPoint.h" 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_WIN 18*c8dee2aaSAndroid Build Coastguard Worker static const char* kBars[] = { ".", "o", "O" }; 19*c8dee2aaSAndroid Build Coastguard Worker #else 20*c8dee2aaSAndroid Build Coastguard Worker static const char* kBars[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" }; 21*c8dee2aaSAndroid Build Coastguard Worker #endif 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker struct Stats { StatsStats24*c8dee2aaSAndroid Build Coastguard Worker Stats(const skia_private::TArray<double>& samples, bool want_plot) { 25*c8dee2aaSAndroid Build Coastguard Worker int n = samples.size(); 26*c8dee2aaSAndroid Build Coastguard Worker if (!n) { 27*c8dee2aaSAndroid Build Coastguard Worker min = max = mean = var = median = 0; 28*c8dee2aaSAndroid Build Coastguard Worker return; 29*c8dee2aaSAndroid Build Coastguard Worker } 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker min = samples[0]; 32*c8dee2aaSAndroid Build Coastguard Worker max = samples[0]; 33*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < n; i++) { 34*c8dee2aaSAndroid Build Coastguard Worker if (samples[i] < min) { min = samples[i]; } 35*c8dee2aaSAndroid Build Coastguard Worker if (samples[i] > max) { max = samples[i]; } 36*c8dee2aaSAndroid Build Coastguard Worker } 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker double sum = 0.0; 39*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0 ; i < n; i++) { 40*c8dee2aaSAndroid Build Coastguard Worker sum += samples[i]; 41*c8dee2aaSAndroid Build Coastguard Worker } 42*c8dee2aaSAndroid Build Coastguard Worker mean = sum / n; 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker double err = 0.0; 45*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0 ; i < n; i++) { 46*c8dee2aaSAndroid Build Coastguard Worker err += (samples[i] - mean) * (samples[i] - mean); 47*c8dee2aaSAndroid Build Coastguard Worker } 48*c8dee2aaSAndroid Build Coastguard Worker var = sk_ieee_double_divide(err, n-1); 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Worker std::vector<double> sorted(samples.begin(), samples.end()); 51*c8dee2aaSAndroid Build Coastguard Worker std::sort(sorted.begin(), sorted.end()); 52*c8dee2aaSAndroid Build Coastguard Worker median = sorted[n/2]; 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker // Normalize samples to [min, max] in as many quanta as we have distinct bars to print. 55*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; want_plot && i < n; i++) { 56*c8dee2aaSAndroid Build Coastguard Worker if (min == max) { 57*c8dee2aaSAndroid Build Coastguard Worker // All samples are the same value. Don't divide by zero. 58*c8dee2aaSAndroid Build Coastguard Worker plot.append(kBars[0]); 59*c8dee2aaSAndroid Build Coastguard Worker continue; 60*c8dee2aaSAndroid Build Coastguard Worker } 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker double s = samples[i]; 63*c8dee2aaSAndroid Build Coastguard Worker s -= min; 64*c8dee2aaSAndroid Build Coastguard Worker s /= (max - min); 65*c8dee2aaSAndroid Build Coastguard Worker s *= (std::size(kBars) - 1); 66*c8dee2aaSAndroid Build Coastguard Worker const size_t bar = (size_t)(s + 0.5); 67*c8dee2aaSAndroid Build Coastguard Worker SkASSERT_RELEASE(bar < std::size(kBars)); 68*c8dee2aaSAndroid Build Coastguard Worker plot.append(kBars[bar]); 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker double min; 73*c8dee2aaSAndroid Build Coastguard Worker double max; 74*c8dee2aaSAndroid Build Coastguard Worker double mean; // Estimate of population mean. 75*c8dee2aaSAndroid Build Coastguard Worker double var; // Estimate of population variance. 76*c8dee2aaSAndroid Build Coastguard Worker double median; 77*c8dee2aaSAndroid Build Coastguard Worker SkString plot; // A single-line bar chart (_not_ histogram) of the samples. 78*c8dee2aaSAndroid Build Coastguard Worker }; 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker #endif//Stats_DEFINED 81