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
1416using namespace graphql ;
1517
1618using 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