1//===-- Measurement.h -------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef __PerfTestDriver__Measurement__
11#define __PerfTestDriver__Measurement__
12
13#include "Gauge.h"
14#include "Timer.h"
15#include "Metric.h"
16#include "MemoryGauge.h"
17
18namespace lldb_perf
19{
20template <typename GaugeType, typename Callable>
21class Measurement
22{
23public:
24    Measurement () :
25        m_gauge (),
26        m_callable (),
27        m_metric ()
28    {
29    }
30
31    Measurement (Callable callable, const char* name, const char* desc)  :
32        m_gauge (),
33        m_callable (callable),
34        m_metric (Metric<typename GaugeType::ValueType>(name, desc))
35    {
36    }
37
38    Measurement (const char* name, const char* desc)  :
39        m_gauge (),
40        m_callable (),
41        m_metric (Metric<typename GaugeType::ValueType>(name, desc))
42    {
43    }
44
45    template <typename GaugeType_Rhs, typename Callable_Rhs>
46    Measurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
47        m_gauge(rhs.GetGauge()),
48        m_callable(rhs.GetCallable()),
49        m_metric(rhs.GetMetric())
50    {
51    }
52
53    template <typename... Args>
54    void
55    operator () (Args... args)
56    {
57        m_gauge.Start();
58        m_callable(args...);
59        m_metric.Append (m_gauge.Stop());
60    }
61
62    virtual const Callable&
63    GetCallable () const
64    {
65        return m_callable;
66    }
67
68    virtual const GaugeType&
69    GetGauge () const
70    {
71        return m_gauge;
72    }
73
74    virtual const Metric<typename GaugeType::ValueType>&
75    GetMetric () const
76    {
77        return m_metric;
78    }
79
80    void
81    Start ()
82    {
83        m_gauge.Start();
84    }
85
86    typename GaugeType::ValueType
87    Stop ()
88    {
89        auto value = m_gauge.Stop();
90        m_metric.Append(value);
91        return value;
92    }
93
94    void
95    WriteStartValue (Results &results)
96    {
97        auto metric = GetMetric ();
98        results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStartValue()));
99    }
100
101    void
102    WriteStopValue (Results &results)
103    {
104        auto metric = GetMetric ();
105        results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStopValue()));
106    }
107
108    void
109    WriteAverageValue (Results &results)
110    {
111        auto metric = GetMetric ();
112        results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetAverage()));
113    }
114
115    void
116    WriteAverageAndStandardDeviation (Results &results)
117    {
118        auto metric = GetMetric ();
119        auto dictionary = (Results::Dictionary*)results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetAverage())).get();
120        if (dictionary)
121        {
122            dictionary->Add("stddev", NULL, lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStandardDeviation()));
123        }
124    }
125
126    void
127    WriteStandardDeviation (Results &results)
128    {
129        auto metric = GetMetric ();
130        results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStandardDeviation()));
131    }
132
133protected:
134    GaugeType m_gauge;
135    Callable m_callable;
136    Metric<typename GaugeType::ValueType> m_metric;
137};
138
139template <typename Callable>
140class TimeMeasurement : public Measurement<TimeGauge,Callable>
141{
142public:
143    TimeMeasurement () :
144        Measurement<TimeGauge,Callable> ()
145    {
146    }
147
148    TimeMeasurement (Callable callable,
149                     const char* name = NULL,
150                     const char* descr = NULL) :
151        Measurement<TimeGauge,Callable> (callable, name, descr)
152    {
153    }
154
155    template <typename Callable_Rhs>
156    TimeMeasurement (const TimeMeasurement<Callable_Rhs>& rhs) :
157        Measurement<TimeGauge,Callable>(rhs)
158    {
159    }
160
161    template <typename GaugeType_Rhs, typename Callable_Rhs>
162    TimeMeasurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
163        Measurement<GaugeType_Rhs,Callable_Rhs>(rhs)
164    {
165    }
166
167    template <typename... Args>
168    void
169    operator () (Args... args)
170    {
171        Measurement<TimeGauge,Callable>::operator()(args...);
172    }
173};
174
175template <typename Callable>
176class MemoryMeasurement : public Measurement<MemoryGauge,Callable>
177{
178public:
179    MemoryMeasurement () : Measurement<MemoryGauge,Callable> ()
180    {
181    }
182
183    MemoryMeasurement (Callable callable,
184                       const char* name,
185                       const char* descr) :
186        Measurement<MemoryGauge,Callable> (callable, name, descr)
187    {
188    }
189
190    MemoryMeasurement (const char* name, const char* descr) :
191        Measurement<MemoryGauge,Callable> (name, descr)
192    {
193    }
194
195    template <typename Callable_Rhs>
196    MemoryMeasurement (const MemoryMeasurement<Callable_Rhs>& rhs) :
197        Measurement<MemoryGauge,Callable>(rhs)
198    {
199    }
200
201    template <typename GaugeType_Rhs, typename Callable_Rhs>
202    MemoryMeasurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
203        Measurement<GaugeType_Rhs,Callable_Rhs>(rhs)
204    {
205    }
206
207    template <typename... Args>
208    void
209    operator () (Args... args)
210    {
211        Measurement<MemoryGauge,Callable>::operator()(args...);
212    }
213};
214
215}
216
217#endif /* defined(__PerfTestDriver__Measurement__) */
218