aboutsummaryrefslogtreecommitdiff
path: root/src/statistics.cc
diff options
context:
space:
mode:
authorFred Tingaud <ftingaud@hotmail.com>2018-04-09 14:40:58 +0200
committerDominic Hamon <dominichamon@users.noreply.github.com>2018-04-09 13:40:58 +0100
commit50ffc781b1df6d582d6a453b9942cc8cb512db69 (patch)
tree6df78a495d6eae2e119575f3d4b6564944acf7df /src/statistics.cc
parent2844167ff99edb63f629c9768ea1f3f94ebfb8fe (diff)
downloadgoogle-benchmark-50ffc781b1df6d582d6a453b9942cc8cb512db69.tar.gz
Optimize by using nth_element instead of partial_sort to find the median. (#565)
Diffstat (limited to 'src/statistics.cc')
-rw-r--r--src/statistics.cc21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/statistics.cc b/src/statistics.cc
index d284367..1c91e10 100644
--- a/src/statistics.cc
+++ b/src/statistics.cc
@@ -36,16 +36,19 @@ double StatisticsMean(const std::vector<double>& v) {
double StatisticsMedian(const std::vector<double>& v) {
if (v.size() < 3) return StatisticsMean(v);
- std::vector<double> partial;
- // we need roundDown(count/2)+1 slots
- partial.resize(1 + (v.size() / 2));
- std::partial_sort_copy(v.begin(), v.end(), partial.begin(), partial.end());
- // did we have odd number of samples?
- // if yes, then the last element of partially-sorted vector is the median
- // it no, then the average of the last two elements is the median
+ std::vector<double> copy(v);
+
+ auto center = copy.begin() + v.size() / 2;
+ std::nth_element(copy.begin(), center, copy.end());
+
+ // did we have an odd number of samples?
+ // if yes, then center is the median
+ // it no, then we are looking for the average between center and the value before
if(v.size() % 2 == 1)
- return partial.back();
- return (partial[partial.size() - 2] + partial[partial.size() - 1]) / 2.0;
+ return *center;
+ auto center2 = copy.begin() + v.size() / 2 - 1;
+ std::nth_element(copy.begin(), center2, copy.end());
+ return (*center + *center2) / 2.0;
}
// Return the sum of the squares of this sample set