-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathbenchmark.cpp
125 lines (102 loc) · 4.02 KB
/
benchmark.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "BenchmarkClient.h"
#include "TodayMock.h"
#include <chrono>
#include <iostream>
#include <iterator>
#include <numeric>
#include <stdexcept>
#include <string>
#include <string_view>
using namespace graphql;
using namespace std::literals;
void outputOverview(
size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept
{
const auto requestsPerSecond =
((static_cast<double>(iterations)
* static_cast<double>(
std::chrono::duration_cast<std::chrono::steady_clock::duration>(1s).count()))
/ static_cast<double>(totalDuration.count()));
const auto averageRequest =
(static_cast<double>(
std::chrono::duration_cast<std::chrono::microseconds>(totalDuration).count())
/ static_cast<double>(iterations));
std::cout << "Throughput: " << requestsPerSecond << " requests/second" << std::endl;
std::cout << "Overall (microseconds): "
<< std::chrono::duration_cast<std::chrono::microseconds>(totalDuration).count()
<< " total, " << averageRequest << " average" << std::endl;
}
void outputSegment(
std::string_view name, std::vector<std::chrono::steady_clock::duration>& durations) noexcept
{
std::sort(durations.begin(), durations.end());
const auto count = durations.size();
const auto total =
std::accumulate(durations.begin(), durations.end(), std::chrono::steady_clock::duration {});
std::cout << name << " (microseconds): "
<< std::chrono::duration_cast<std::chrono::microseconds>(durations[count / 2]).count()
<< " median, "
<< std::chrono::duration_cast<std::chrono::microseconds>(durations.front()).count()
<< " minimum, "
<< std::chrono::duration_cast<std::chrono::microseconds>(durations.back()).count()
<< " maximum, "
<< (static_cast<double>(
std::chrono::duration_cast<std::chrono::microseconds>(total).count())
/ static_cast<double>(count))
<< " average" << std::endl;
}
int main(int argc, char** argv)
{
const size_t iterations = [](const char* arg) noexcept -> size_t {
if (arg)
{
const int parsed = std::atoi(arg);
if (parsed > 0)
{
return static_cast<size_t>(parsed);
}
}
// Default to 100 iterations
return 100;
}((argc > 1) ? argv[1] : nullptr);
std::cout << "Iterations: " << iterations << std::endl;
const auto mockService = today::mock_service();
const auto& service = mockService->service;
std::vector<std::chrono::steady_clock::duration> durationResolve(iterations);
std::vector<std::chrono::steady_clock::duration> durationParseServiceResponse(iterations);
std::vector<std::chrono::steady_clock::duration> durationParseResponse(iterations);
const auto startTime = std::chrono::steady_clock::now();
try
{
using namespace client::query::Query;
auto query = GetRequestObject();
const auto& name = GetOperationName();
for (size_t i = 0; i < iterations; ++i)
{
const auto startResolve = std::chrono::steady_clock::now();
auto response = service->resolve({ query, name }).get();
const auto startParseServiceResponse = std::chrono::steady_clock::now();
auto serviceResponse = client::parseServiceResponse(std::move(response));
const auto startParseResponse = std::chrono::steady_clock::now();
const auto parsed = parseResponse(std::move(serviceResponse.data));
const auto endParseResponse = std::chrono::steady_clock::now();
durationResolve[i] = startParseServiceResponse - startResolve;
durationParseServiceResponse[i] = startParseResponse - startParseServiceResponse;
durationParseResponse[i] = endParseResponse - startParseResponse;
}
}
catch (const std::runtime_error& ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}
const auto endTime = std::chrono::steady_clock::now();
const auto totalDuration = endTime - startTime;
outputOverview(iterations, totalDuration);
outputSegment("Resolve"sv, durationResolve);
outputSegment("ParseServiceResponse"sv, durationParseServiceResponse);
outputSegment("ParseResponse"sv, durationParseResponse);
return 0;
}