Skip to content

Commit ecec3d0

Browse files
authored
Merge pull request #153 from wravery/main
Fix #148
2 parents b3210c8 + baa178b commit ecec3d0

File tree

1 file changed

+104
-25
lines changed

1 file changed

+104
-25
lines changed

samples/today/benchmark.cpp

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,28 @@
55

66
#include "graphqlservice/JSONResponse.h"
77

8-
#include <cstdio>
8+
#include <chrono>
99
#include <iostream>
1010
#include <iterator>
11-
#include <sstream>
11+
#include <numeric>
1212
#include <stdexcept>
13+
#include <string>
14+
#include <string_view>
1315

1416
using namespace graphql;
1517

1618
using namespace std::literals;
1719

18-
int main(int argc, char** argv)
19-
{
20-
response::IdType binAppointmentId;
21-
response::IdType binTaskId;
22-
response::IdType binFolderId;
20+
namespace {
21+
22+
response::IdType binAppointmentId;
23+
response::IdType binTaskId;
24+
response::IdType binFolderId;
25+
26+
} // namespace
2327

28+
std::shared_ptr<today::Operations> buildService()
29+
{
2430
std::string fakeAppointmentId("fakeAppointmentId");
2531
binAppointmentId.resize(fakeAppointmentId.size());
2632
std::copy(fakeAppointmentId.cbegin(), fakeAppointmentId.cend(), binAppointmentId.begin());
@@ -34,19 +40,16 @@ int main(int argc, char** argv)
3440
std::copy(fakeFolderId.cbegin(), fakeFolderId.cend(), binFolderId.begin());
3541

3642
auto query = std::make_shared<today::Query>(
37-
[&binAppointmentId]() -> std::vector<std::shared_ptr<today::Appointment>> {
38-
std::cout << "Called getAppointments..." << std::endl;
43+
[]() -> std::vector<std::shared_ptr<today::Appointment>> {
3944
return { std::make_shared<today::Appointment>(std::move(binAppointmentId),
4045
"tomorrow",
4146
"Lunch?",
4247
false) };
4348
},
44-
[&binTaskId]() -> std::vector<std::shared_ptr<today::Task>> {
45-
std::cout << "Called getTasks..." << std::endl;
49+
[]() -> std::vector<std::shared_ptr<today::Task>> {
4650
return { std::make_shared<today::Task>(std::move(binTaskId), "Don't forget", true) };
4751
},
48-
[&binFolderId]() -> std::vector<std::shared_ptr<today::Folder>> {
49-
std::cout << "Called getUnreadCounts..." << std::endl;
52+
[]() -> std::vector<std::shared_ptr<today::Folder>> {
5053
return { std::make_shared<today::Folder>(std::move(binFolderId), "\"Fake\" Inbox", 3) };
5154
});
5255
auto mutation = std::make_shared<today::Mutation>(
@@ -60,8 +63,53 @@ int main(int argc, char** argv)
6063
auto subscription = std::make_shared<today::Subscription>();
6164
auto service = std::make_shared<today::Operations>(query, mutation, subscription);
6265

63-
std::cout << "Created the service..." << std::endl;
66+
return service;
67+
}
6468

69+
void outputOverview(
70+
size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept
71+
{
72+
const auto requestsPerSecond =
73+
((static_cast<double>(iterations)
74+
* static_cast<double>(
75+
std::chrono::duration_cast<std::chrono::steady_clock::duration>(1s).count()))
76+
/ static_cast<double>(totalDuration.count()));
77+
const auto averageRequest =
78+
(static_cast<double>(
79+
std::chrono::duration_cast<std::chrono::microseconds>(totalDuration).count())
80+
/ static_cast<double>(iterations));
81+
82+
std::cout << "Throughput: " << requestsPerSecond << " requests/second" << std::endl;
83+
84+
std::cout << "Overall (microseconds): "
85+
<< std::chrono::duration_cast<std::chrono::microseconds>(totalDuration).count()
86+
<< " total, " << averageRequest << " average" << std::endl;
87+
}
88+
89+
void outputSegment(
90+
std::string_view name, std::vector<std::chrono::steady_clock::duration>& durations) noexcept
91+
{
92+
std::sort(durations.begin(), durations.end());
93+
94+
const auto count = durations.size();
95+
const auto total =
96+
std::accumulate(durations.begin(), durations.end(), std::chrono::steady_clock::duration {});
97+
98+
std::cout << name << " (microseconds): "
99+
<< std::chrono::duration_cast<std::chrono::microseconds>(durations[count / 2]).count()
100+
<< " median, "
101+
<< std::chrono::duration_cast<std::chrono::microseconds>(durations.front()).count()
102+
<< " minimum, "
103+
<< std::chrono::duration_cast<std::chrono::microseconds>(durations.back()).count()
104+
<< " maximum, "
105+
<< (static_cast<double>(
106+
std::chrono::duration_cast<std::chrono::microseconds>(total).count())
107+
/ static_cast<double>(count))
108+
<< " average" << std::endl;
109+
}
110+
111+
int main(int argc, char** argv)
112+
{
65113
const size_t iterations = [](const char* arg) noexcept -> size_t {
66114
if (arg)
67115
{
@@ -77,10 +125,20 @@ int main(int argc, char** argv)
77125
return 100;
78126
}((argc > 1) ? argv[1] : nullptr);
79127

80-
for (size_t i = 0; i < iterations; ++i)
128+
std::cout << "Iterations: " << iterations << std::endl;
129+
130+
auto service = buildService();
131+
std::vector<std::chrono::steady_clock::duration> durationParse(iterations);
132+
std::vector<std::chrono::steady_clock::duration> durationValidate(iterations);
133+
std::vector<std::chrono::steady_clock::duration> durationResolve(iterations);
134+
std::vector<std::chrono::steady_clock::duration> durationToJson(iterations);
135+
const auto startTime = std::chrono::steady_clock::now();
136+
137+
try
81138
{
82-
try
139+
for (size_t i = 0; i < iterations; ++i)
83140
{
141+
const auto startParse = std::chrono::steady_clock::now();
84142
auto query = peg::parseString(R"gql(query {
85143
appointments {
86144
pageInfo { hasNextPage }
@@ -94,19 +152,40 @@ int main(int argc, char** argv)
94152
}
95153
}
96154
})gql"sv);
155+
const auto startValidate = std::chrono::steady_clock::now();
97156

98-
std::cout << "Executing query..." << std::endl;
157+
service->validate(query);
99158

100-
std::cout << response::toJSON(
101-
service->resolve(nullptr, query, "", response::Value(response::Type::Map)).get())
102-
<< std::endl;
103-
}
104-
catch (const std::runtime_error& ex)
105-
{
106-
std::cerr << ex.what() << std::endl;
107-
return 1;
159+
const auto startResolve = std::chrono::steady_clock::now();
160+
auto response =
161+
service->resolve(nullptr, query, "", response::Value(response::Type::Map)).get();
162+
const auto startToJson = std::chrono::steady_clock::now();
163+
164+
response::toJSON(std::move(response));
165+
166+
const auto endToJson = std::chrono::steady_clock::now();
167+
168+
durationParse[i] = startValidate - startParse;
169+
durationValidate[i] = startResolve - startValidate;
170+
durationResolve[i] = startToJson - startResolve;
171+
durationToJson[i] = endToJson - startToJson;
108172
}
109173
}
174+
catch (const std::runtime_error& ex)
175+
{
176+
std::cerr << ex.what() << std::endl;
177+
return 1;
178+
}
179+
180+
const auto endTime = std::chrono::steady_clock::now();
181+
const auto totalDuration = endTime - startTime;
182+
183+
outputOverview(iterations, totalDuration);
184+
185+
outputSegment("Parse"sv, durationParse);
186+
outputSegment("Validate"sv, durationValidate);
187+
outputSegment("Resolve"sv, durationResolve);
188+
outputSegment("ToJSON"sv, durationToJson);
110189

111190
return 0;
112191
}

0 commit comments

Comments
 (0)