29
29
#include " BenchFeature.h"
30
30
31
31
#include < ctime>
32
- #include < iomanip>
33
32
#include < fstream>
33
+ #include < iomanip>
34
34
#include < iostream>
35
35
36
36
#ifdef TRI_HAVE_UNISTD_H
39
39
40
40
#include " ApplicationFeatures/ApplicationServer.h"
41
41
#include " Basics/FileUtils.h"
42
+ #include " Basics/NumberOfCores.h"
42
43
#include " Basics/StaticStrings.h"
43
44
#include " Basics/StringUtils.h"
44
45
#include " Basics/Utf8Helper.h"
45
46
#include " Basics/application-exit.h"
46
47
#include " Basics/files.h"
47
48
#include " Basics/system-functions.h"
48
- #include " Logger/Logger.h"
49
- #include " Logger/LogMacros.h"
50
49
#include " Benchmark/BenchmarkCounter.h"
51
50
#include " Benchmark/BenchmarkOperation.h"
52
51
#include " Benchmark/BenchmarkStats.h"
53
52
#include " Benchmark/BenchmarkThread.h"
54
53
#include " FeaturePhases/BasicFeaturePhaseClient.h"
54
+ #include " Logger/LogMacros.h"
55
+ #include " Logger/Logger.h"
55
56
#include " ProgramOptions/ProgramOptions.h"
56
57
#include " ProgramOptions/Section.h"
57
58
#include " Shell/ClientFeature.h"
@@ -75,7 +76,7 @@ using namespace arangodb::rest;
75
76
76
77
BenchFeature::BenchFeature (application_features::ApplicationServer& server, int * result)
77
78
: ApplicationFeature(server, " Bench" ),
78
- _concurrency(1 ),
79
+ _concurrency(NumberOfCores::getValue() ),
79
80
_operations(1000 ),
80
81
_realOperations(0 ),
81
82
_batchSize(0 ),
@@ -139,11 +140,10 @@ void BenchFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
139
140
options->addOption (" --histogram.num-intervals" ,
140
141
" number of buckets (resolution)" ,
141
142
new UInt64Parameter (&_histogramNumIntervals));
142
- options->addOption (" --histogram.percentiles" ,
143
- " which percentiles to calculate" ,
143
+ options->addOption (" --histogram.percentiles" , " which percentiles to calculate" ,
144
144
new VectorParameter<DoubleParameter>(&_percentiles),
145
145
arangodb::options::makeDefaultFlags (options::Flags::FlushOnFirst));
146
-
146
+
147
147
options->addOption (" --async" , " send asynchronous requests" , new BooleanParameter (&_async));
148
148
149
149
options->addOption (" --concurrency" ,
@@ -178,7 +178,8 @@ void BenchFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
178
178
new BooleanParameter (&_waitForSync));
179
179
180
180
options->addOption (" --create-database" ,
181
- " whether we should create the database specified via the server connection" ,
181
+ " whether we should create the database specified via the "
182
+ " server connection" ,
182
183
new BooleanParameter (&_createDatabase));
183
184
184
185
options->addOption (" --duration" ,
@@ -216,16 +217,25 @@ void BenchFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
216
217
options->addOption (" --progress" , " log intermediate progress" ,
217
218
new BooleanParameter (&_progress));
218
219
219
- options->addOption (" --custom-query" , " the query to be used in the 'custom-query' testcase" ,
220
- new StringParameter (&_customQuery)).setIntroducedIn (30800 );
221
-
222
- options->addOption (" --custom-query-file" , " path to a file with the query to be used in the 'custom-query' testcase. "
223
- " If --custom-query is specified as well, it has higher priority." ,
224
- new StringParameter (&_customQueryFile)).setIntroducedIn (30800 );
225
-
220
+ options
221
+ ->addOption (" --custom-query" ,
222
+ " the query to be used in the 'custom-query' testcase" ,
223
+ new StringParameter (&_customQuery))
224
+ .setIntroducedIn (30800 );
225
+
226
+ options
227
+ ->addOption (
228
+ " --custom-query-file" ,
229
+ " path to a file with the query to be used in the 'custom-query' "
230
+ " testcase. "
231
+ " If --custom-query is specified as well, it has higher priority." ,
232
+ new StringParameter (&_customQueryFile))
233
+ .setIntroducedIn (30800 );
234
+
226
235
options->addOption (" --quiet" , " suppress status messages" , new BooleanParameter (&_quiet));
227
-
228
- options->addObsoleteOption (" --verbose" , " print out replies if the HTTP header indicates DB errors" , false );
236
+
237
+ options->addObsoleteOption (
238
+ " --verbose" , " print out replies if the HTTP header indicates DB errors" , false );
229
239
}
230
240
231
241
void BenchFeature::status (std::string const & value) {
@@ -241,8 +251,8 @@ void BenchFeature::updateStartCounter() { ++_started; }
241
251
int BenchFeature::getStartCounter () { return _started; }
242
252
243
253
void BenchFeature::start () {
244
- sort (_percentiles.begin (), _percentiles.end ());
245
-
254
+ std:: sort (_percentiles.begin (), _percentiles.end ());
255
+
246
256
if (!_jsonReportFile.empty () && FileUtils::exists (_jsonReportFile)) {
247
257
LOG_TOPIC (" ee2a4" , FATAL, arangodb::Logger::BENCH)
248
258
<< " file already exists: '" << _jsonReportFile << " ' - won't overwrite it." ;
@@ -261,14 +271,13 @@ void BenchFeature::start() {
261
271
b.openObject ();
262
272
b.add (" name" , VPackValue (normalizeUtf8ToNFC (connectDB)));
263
273
b.close ();
264
-
274
+
265
275
std::unordered_map<std::string, std::string> headers;
266
276
headers.emplace (StaticStrings::ContentTypeHeader, StaticStrings::MimeTypeVPack);
267
277
268
278
auto result = createDbClient->request (rest::RequestType::POST,
269
- " /_api/database" ,
270
- b.slice ().startAs <char >(), b.slice ().byteSize (),
271
- headers);
279
+ " /_api/database" , b.slice ().startAs <char >(),
280
+ b.slice ().byteSize (), headers);
272
281
273
282
if (!result || result->wasHttpError ()) {
274
283
std::string msg;
@@ -278,7 +287,7 @@ void BenchFeature::start() {
278
287
}
279
288
280
289
LOG_TOPIC (" 5cda8" , FATAL, arangodb::Logger::BENCH)
281
- << " failed to create the specified database: " << msg;
290
+ << " failed to create the specified database: " << msg;
282
291
FATAL_ERROR_EXIT ();
283
292
}
284
293
@@ -289,7 +298,8 @@ void BenchFeature::start() {
289
298
290
299
*_result = ret;
291
300
292
- std::unique_ptr<BenchmarkOperation> benchmark = BenchmarkOperation::createBenchmark (_testCase, *this );
301
+ std::unique_ptr<BenchmarkOperation> benchmark =
302
+ BenchmarkOperation::createBenchmark (_testCase, *this );
293
303
294
304
if (benchmark == nullptr ) {
295
305
LOG_TOPIC (" ee2a5" , FATAL, arangodb::Logger::BENCH)
@@ -298,10 +308,11 @@ void BenchFeature::start() {
298
308
}
299
309
300
310
LOG_TOPIC (" 69091" , INFO, arangodb::Logger::BENCH)
301
- << " Running test case '" << _testCase << " ': " << benchmark->getDescription ();
311
+ << " Running test case '" << _testCase << " ': " << benchmark->getDescription ();
302
312
if (benchmark->isDeprecated ()) {
303
313
LOG_TOPIC (" caf8a" , WARN, arangodb::Logger::BENCH)
304
- << " Please note: this test case is deprecated and will be removed in a future version." ;
314
+ << " Please note: this test case is deprecated and will be removed in a "
315
+ " future version." ;
305
316
}
306
317
307
318
if (_duration != 0 ) {
@@ -323,10 +334,10 @@ void BenchFeature::start() {
323
334
// add some more offset so we don't get into trouble with threads of different
324
335
// speed
325
336
realStep += 10000 ;
326
-
337
+
327
338
// aggregated stats for all runs
328
339
BenchmarkStats totalStats;
329
-
340
+
330
341
auto builder = std::make_shared<VPackBuilder>();
331
342
builder->openObject ();
332
343
builder->add (" histogram" , VPackValue (VPackValueType::Object));
@@ -336,7 +347,8 @@ void BenchFeature::start() {
336
347
std::stringstream pp;
337
348
pp << " Interval/Percentile:" ;
338
349
for (auto percentile : _percentiles) {
339
- pp << std::fixed << std::right << std::setw (12 ) << std::setprecision (2 ) << percentile << " %" ;
350
+ pp << std::fixed << std::right << std::setw (12 ) << std::setprecision (2 )
351
+ << percentile << " %" ;
340
352
}
341
353
pp << std::endl;
342
354
@@ -356,11 +368,9 @@ void BenchFeature::start() {
356
368
357
369
for (uint64_t i = 0 ; i < _concurrency; ++i) {
358
370
auto thread = std::make_unique<BenchmarkThread>(
359
- server (), benchmark.get (), &startCondition,
360
- &BenchFeature::updateStartCounter, static_cast <int >(i),
361
- _batchSize, &operationsCounter,
362
- client, _keepAlive, _async,
363
- _histogramIntervalSize, _histogramNumIntervals);
371
+ server (), benchmark.get (), &startCondition, &BenchFeature::updateStartCounter,
372
+ static_cast <int >(i), _batchSize, &operationsCounter, client,
373
+ _keepAlive, _async, _histogramIntervalSize, _histogramNumIntervals);
364
374
thread->setOffset (i * realStep);
365
375
thread->start ();
366
376
threads.push_back (std::move (thread));
@@ -400,10 +410,11 @@ void BenchFeature::start() {
400
410
}
401
411
402
412
if (_progress && numOperations >= nextReportValue) {
403
- LOG_TOPIC (" c3604" , INFO, arangodb::Logger::BENCH) << " number of operations: " << nextReportValue;
413
+ LOG_TOPIC (" c3604" , INFO, arangodb::Logger::BENCH)
414
+ << " number of operations: " << nextReportValue;
404
415
nextReportValue += stepValue;
405
416
}
406
-
417
+
407
418
std::this_thread::sleep_for (std::chrono::milliseconds (5 ));
408
419
}
409
420
@@ -476,7 +487,9 @@ void BenchFeature::start() {
476
487
*_result = ret;
477
488
}
478
489
479
- bool BenchFeature::report (ClientFeature& client, std::vector<BenchRunResult> results, BenchmarkStats const & stats, std::string const & histogram, VPackBuilder& builder) {
490
+ bool BenchFeature::report (ClientFeature& client, std::vector<BenchRunResult> results,
491
+ BenchmarkStats const & stats,
492
+ std::string const & histogram, VPackBuilder& builder) {
480
493
std::cout << std::endl;
481
494
482
495
std::cout << " Total number of operations: " << _realOperations << " , runs: " << _runs
@@ -505,7 +518,6 @@ bool BenchFeature::report(ClientFeature& client, std::vector<BenchRunResult> res
505
518
builder.add (" database" , VPackValue (client.databaseName ()));
506
519
builder.add (" collection" , VPackValue (_collection));
507
520
508
-
509
521
std::sort (results.begin (), results.end (),
510
522
[](BenchRunResult a, BenchRunResult b) { return a._time < b._time ; });
511
523
@@ -516,11 +528,11 @@ bool BenchFeature::report(ClientFeature& client, std::vector<BenchRunResult> res
516
528
std::cout << std::endl;
517
529
std::cout << " Printing fastest result" << std::endl;
518
530
std::cout << " =======================" << std::endl;
519
-
531
+
520
532
builder.add (" fastestResults" , VPackValue (VPackValueType::Object));
521
533
printResult (results[0 ], builder);
522
534
builder.close ();
523
-
535
+
524
536
std::cout << " Printing slowest result" << std::endl;
525
537
std::cout << " =======================" << std::endl;
526
538
@@ -549,16 +561,19 @@ bool BenchFeature::report(ClientFeature& client, std::vector<BenchRunResult> res
549
561
printResult (output, builder);
550
562
builder.close ();
551
563
552
- std::cout <<
553
- " Min request time: " << std::setprecision (6 ) << (stats.min * 1000 ) << " ms" << std::endl <<
554
- " Avg request time: " << std::setprecision (6 ) << (stats.avg () * 1000 ) << " ms" << std::endl <<
555
- " Max request time: " << std::setprecision (6 ) << (stats.max * 1000 ) << " ms" << std::endl << std::endl;
564
+ std::cout << " Min request time: " << std::setprecision (6 )
565
+ << (stats.min * 1000 ) << " ms" << std::endl
566
+ << " Avg request time: " << std::setprecision (6 )
567
+ << (stats.avg () * 1000 ) << " ms" << std::endl
568
+ << " Max request time: " << std::setprecision (6 )
569
+ << (stats.max * 1000 ) << " ms" << std::endl
570
+ << std::endl;
556
571
557
572
std::cout << histogram;
558
573
559
574
builder.add (" min" , VPackValue (stats.min ));
560
575
builder.add (" avg" , VPackValue (stats.avg ()));
561
- builder.add (" max" , VPackValue (stats.max ));
576
+ builder.add (" max" , VPackValue (stats.max ));
562
577
builder.close ();
563
578
564
579
if (!_jsonReportFile.empty ()) {
@@ -617,25 +632,26 @@ void BenchFeature::printResult(BenchRunResult const& result, VPackBuilder& build
617
632
builder.add (" requestTime" , VPackValue (result._requestTime ));
618
633
std::cout << " Request/response duration (per thread): " << std::fixed
619
634
<< (result._requestTime / (double )_concurrency) << " s" << std::endl;
620
- builder.add (" requestResponseDurationPerThread" , VPackValue (result._requestTime / (double )_concurrency));
635
+ builder.add (" requestResponseDurationPerThread" ,
636
+ VPackValue (result._requestTime / (double )_concurrency));
621
637
622
638
std::cout << " Time needed per operation: " << std::fixed
623
639
<< (result._time / _realOperations) << " s" << std::endl;
624
640
builder.add (" timeNeededPerOperation" , VPackValue (result._time / _realOperations));
625
-
641
+
626
642
std::cout << " Time needed per operation per thread: " << std::fixed
627
643
<< (result._time / (double )_realOperations * (double )_concurrency)
628
644
<< " s" << std::endl;
629
- builder.add (" timeNeededPerOperationPerThread" , VPackValue (
630
- result._time / (double )_realOperations * (double )_concurrency));
631
-
645
+ builder.add (" timeNeededPerOperationPerThread" ,
646
+ VPackValue ( result._time / (double )_realOperations * (double )_concurrency));
647
+
632
648
std::cout << " Operations per second rate: " << std::fixed
633
649
<< ((double )_realOperations / result._time ) << std::endl;
634
- builder.add (" operationsPerSecondRate" ,
650
+ builder.add (" operationsPerSecondRate" ,
635
651
VPackValue ((double )_realOperations / result._time ));
636
-
637
- std::cout << " Elapsed time since start: " << std::fixed << result._time << " s "
638
- << std::endl
652
+
653
+ std::cout << " Elapsed time since start: " << std::fixed << result._time
654
+ << " s " << std::endl
639
655
<< std::endl;
640
656
builder.add (" timeSinceStart" , VPackValue (result._time ));
641
657
0 commit comments