Skip to content

Commit c9bc8f1

Browse files
iwysiupatrickfreed
authored andcommitted
CXX-1383 implement composite score collector
1 parent 91e7f14 commit c9bc8f1

19 files changed

+422
-194
lines changed

benchmark/CMakeLists.txt

+14-4
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,19 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
2626
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Gv")
2727
endif()
2828

29-
add_custom_target(benchmark DEPENDS run_benchmark)
29+
include_directories(
30+
${CMAKE_INSTALL_PREFIX}/${BSONCXX_HEADER_INSTALL_DIR}
31+
${CMAKE_INSTALL_PREFIX}/${MONGOCXX_HEADER_INSTALL_DIR}
32+
)
3033

31-
add_library(run_benchmark benchmark_runner.cpp score_recorder.cpp bson_encoding.hpp)
34+
set(BENCHMARK_LIBRARY
35+
benchmark_runner.cpp
36+
main.cpp
37+
microbench.cpp
38+
score_recorder.cpp
39+
)
3240

33-
target_include_directories(run_benchmark PUBLIC "/usr/local/include/mongocxx/v_noabi" "/usr/local/include/bsoncxx/v_noabi")
34-
target_link_libraries(run_benchmark mongocxx bsoncxx)
41+
add_executable(microbenchmarks ${BENCHMARK_LIBRARY})
42+
set(THREADS_PREFER_PTHREAD_FLAG ON)
43+
find_package(Threads REQUIRED)
44+
target_link_libraries(microbenchmarks mongocxx bsoncxx Threads::Threads)

benchmark/benchmark_runner.cpp

+72-48
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include <chrono>
15+
#include "benchmark_runner.hpp"
1616

17-
#include <mongocxx/instance.hpp>
1817
#include "bson/bson_encoding.hpp"
19-
#include "microbench.hpp"
2018
#include "multi_doc/bulk_insert.hpp"
2119
#include "multi_doc/find_many.hpp"
2220
#include "multi_doc/gridfs_download.hpp"
@@ -26,60 +24,86 @@
2624
#include "single_doc/run_command.hpp"
2725

2826
namespace benchmark {
29-
const std::chrono::duration<int, std::milli> mintime{60000};
30-
const std::chrono::duration<int, std::milli> maxtime{300000};
3127

32-
bool finished_running(const std::chrono::duration<int, std::milli>& curr_time, std::uint32_t iter) {
33-
return (curr_time > maxtime || (curr_time > mintime && iter > 100));
34-
}
28+
// The task sizes and iteration numbers come from the Driver Perfomance Benchmarking Reference Doc.
29+
benchmark_runner::benchmark_runner() {
30+
using bsoncxx::stdx::make_unique;
3531

36-
void run_microbench(microbench* bench,
37-
bsoncxx::stdx::string_view input_json_filename = bsoncxx::stdx::string_view()) {
38-
bench->setup(input_json_filename);
32+
// Bson microbenchmarks
33+
_microbenches.push_back(make_unique<bson_encoding>(75.31, "extended_bson/flat_bson.json"));
34+
_microbenches.push_back(make_unique<bson_encoding>(19.64, "extended_bson/deep_bson.json"));
35+
_microbenches.push_back(make_unique<bson_encoding>(57.34, "extended_bson/full_bson.json"));
36+
// TODO CXX-1241: Add bson_decoding equivalents.
3937

40-
for (std::uint32_t iteration = 0; !finished_running(bench->get_execution_time(), iteration);
41-
iteration++) {
42-
bench->before_task();
38+
// Single doc microbenchmarks
39+
_microbenches.push_back(make_unique<run_command>());
40+
_microbenches.push_back(make_unique<find_one_by_id>("single_and_multi_document/tweet.json"));
41+
_microbenches.push_back(
42+
make_unique<insert_one>(2.75, 10000, "single_and_multi_document/small_doc.json"));
43+
_microbenches.push_back(
44+
make_unique<insert_one>(27.31, 10, "single_and_multi_document/large_doc.json"));
4345

44-
bench->do_task();
46+
// Multi doc microbenchmarks
47+
_microbenches.push_back(make_unique<find_many>("single_and_multi_document/tweet.json"));
48+
_microbenches.push_back(
49+
make_unique<bulk_insert>(2.75, 10000, "single_and_multi_document/small_doc.json"));
50+
_microbenches.push_back(
51+
make_unique<bulk_insert>(27.31, 10, "single_and_multi_document/large_doc.json"));
52+
_microbenches.push_back(
53+
make_unique<gridfs_upload>("single_and_multi_document/gridfs_large.bin"));
54+
_microbenches.push_back(
55+
make_unique<gridfs_download>("single_and_multi_document/gridfs_large.bin"));
4556

46-
bench->after_task();
47-
}
48-
bench->teardown();
57+
// TODO CXX-1378: add parallel microbenchmarks
4958
}
5059

51-
// this would run the benchmarks and collect the data.
52-
int main() {
60+
void benchmark_runner::run_microbenches(benchmark_type tag) {
5361
mongocxx::instance instance{};
5462

55-
bson_encoding flat_bson_encode;
56-
run_microbench(&flat_bson_encode, "FLAT_BSON.json");
57-
bson_encoding deep_bson_encode;
58-
run_microbench(&deep_bson_encode, "DEEP_BSON.json");
59-
bson_encoding full_bson_encode;
60-
run_microbench(&full_bson_encode, "FULL_BSON.json");
61-
// TODO CXX-1241: Add bson_decoding equivalents.
63+
for (std::unique_ptr<microbench>& bench : _microbenches) {
64+
if (tag == benchmark::benchmark_type::all_benchmarks || bench->has_tag(tag)) {
65+
bench->run();
66+
}
67+
}
68+
}
69+
70+
double benchmark_runner::calculate_average(benchmark_type tag) {
71+
std::uint32_t count = 0;
72+
double total = 0.0;
73+
for (std::unique_ptr<microbench>& bench : _microbenches) {
74+
if (bench->has_tag(tag)) {
75+
count++;
76+
total += bench->get_results().get_score();
77+
}
78+
}
79+
return total / static_cast<double>(count);
80+
}
81+
82+
double benchmark_runner::calculate_bson_bench_score() {
83+
return calculate_average(benchmark_type::bson_bench);
84+
}
85+
86+
double benchmark_runner::calculate_single_bench_score() {
87+
return calculate_average(benchmark_type::single_bench);
88+
}
89+
90+
double benchmark_runner::calculate_multi_bench_score() {
91+
return calculate_average(benchmark_type::multi_bench);
92+
}
93+
94+
double benchmark_runner::calculate_parallel_bench_score() {
95+
return calculate_average(benchmark_type::parallel_bench);
96+
}
97+
98+
double benchmark_runner::calculate_read_bench_score() {
99+
return calculate_average(benchmark_type::read_bench);
100+
}
101+
102+
double benchmark_runner::calculate_write_bench_score() {
103+
return calculate_average(benchmark_type::write_bench);
104+
}
62105

63-
run_command run_command_bench;
64-
run_microbench(&run_command_bench);
65-
find_one_by_id find_one_by_id_bench;
66-
run_microbench(&find_one_by_id_bench, "TWEET.json");
67-
insert_one small_doc_insert_one(10000);
68-
run_microbench(&small_doc_insert_one, "SMALL_DOC.json");
69-
insert_one large_doc_insert_one(10);
70-
run_microbench(&large_doc_insert_one, "LARGE_DOC.json");
71-
72-
find_many find_many_bench;
73-
run_microbench(&find_many_bench, "TWEET.json");
74-
bulk_insert small_doc_bulk_insert{10000};
75-
run_microbench(&small_doc_bulk_insert, "SMALL_DOC.json");
76-
bulk_insert large_doc_bulk_insert{10};
77-
run_microbench(&large_doc_bulk_insert, "LARGE_DOC.json");
78-
gridfs_upload gridfs_upload_bench;
79-
run_microbench(&gridfs_upload_bench, "GRIDFS_LARGE.bin");
80-
gridfs_download gridfs_download_bench;
81-
run_microbench(&gridfs_download_bench, "GRIDFS_LARGE.bin");
82-
83-
// get results from the microbenches...
106+
double benchmark_runner::calculate_driver_bench_score() {
107+
return (calculate_read_bench_score() + calculate_write_bench_score()) / 2.0;
84108
}
85109
}

benchmark/benchmark_runner.hpp

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2017 MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include <mongocxx/instance.hpp>
18+
19+
#include "microbench.hpp"
20+
21+
namespace benchmark {
22+
23+
class benchmark_runner {
24+
// this would run the benchmarks and collect the data.
25+
26+
public:
27+
// Initialize microbenchmarks with the size in MB of their tasks and, if necessary, number of
28+
// iterations if multiple microbenchmarks use a subclass.
29+
benchmark_runner();
30+
31+
void run_microbenches(benchmark_type type = benchmark_type::all_benchmarks);
32+
33+
double calculate_bson_bench_score();
34+
35+
double calculate_single_bench_score();
36+
37+
double calculate_multi_bench_score();
38+
39+
double calculate_parallel_bench_score();
40+
41+
double calculate_read_bench_score();
42+
43+
double calculate_write_bench_score();
44+
45+
double calculate_driver_bench_score();
46+
47+
private:
48+
double calculate_average(benchmark_type);
49+
50+
std::vector<std::unique_ptr<microbench>> _microbenches;
51+
};
52+
}

benchmark/bson/bson_decoding.hpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ namespace benchmark {
2020

2121
class bson_decoding : public microbench {
2222
public:
23-
bson_decoding() : microbench{10000} {}
23+
bson_decoding() = delete;
2424

25-
void setup(bsoncxx::stdx::string_view);
25+
bson_decoding(double task_size, bsoncxx::stdx::string_view json_file)
26+
: microbench{task_size, "bson_decoding"} {
27+
_tags.insert(benchmark_type::bson_bench);
28+
_json = parse_json_file_to_strings(json_file)[0];
29+
}
2630

2731
protected:
2832
void task();
@@ -31,10 +35,6 @@ class bson_decoding : public microbench {
3135
std::string _json;
3236
}
3337

34-
void bson_decoding::setup(bsoncxx::stdx::string_view json_file){
35-
_json = parse_json_file_to_strings(json_file)[0];
36-
}
37-
3838
void bson_decoding::task() {
3939
for (std::uint32_t i = 0; i < 10000; i++) {
4040
// TODO CXX-1241: call bson_as_extended json on _json.

benchmark/bson/bson_encoding.hpp

+29-8
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,52 @@
1515
#pragma once
1616

1717
#include <bsoncxx/json.hpp>
18+
#include <bsoncxx/types.hpp>
19+
20+
#include <iostream>
1821
#include "../microbench.hpp"
1922

2023
namespace benchmark {
2124

2225
class bson_encoding : public microbench {
2326
public:
2427
// TODO: need to wait for scoring object to be finished to implement constructor
25-
bson_encoding() : microbench{10000} {}
28+
bson_encoding() = delete;
2629

27-
void setup(bsoncxx::stdx::string_view);
30+
bson_encoding(double task_size, bsoncxx::stdx::string_view json_file)
31+
: microbench{task_size, "bson_encoding"},
32+
_json{parse_json_file_to_strings(json_file)[0]},
33+
_doc{bsoncxx::from_json(bsoncxx::stdx::string_view{_json})} {
34+
_tags.insert(benchmark_type::bson_bench);
35+
}
2836

2937
protected:
3038
void task();
39+
void teardown();
3140

3241
private:
42+
std::int64_t _x;
43+
std::string _s;
3344
std::string _json;
45+
bsoncxx::document::value _doc;
3446
};
3547

36-
void bson_encoding::setup(bsoncxx::stdx::string_view json_file) {
37-
_json = parse_json_file_to_strings(json_file)[0];
38-
}
39-
4048
void bson_encoding::task() {
41-
for (std::uint32_t i = 0; i < 10000; i++) {
42-
bsoncxx::document::value doc = bsoncxx::from_json(bsoncxx::stdx::string_view{_json});
49+
// bsoncxx::stdx::string_view json_view{_json};
50+
// for (std::uint32_t i = 0; i < 10000; i++) {
51+
// bsoncxx::from_json(bsoncxx::stdx::string_view{_json});
52+
//}
53+
_x = 0;
54+
for (auto&& it : _doc.view()) {
55+
if (it.type() == bsoncxx::type::k_utf8) {
56+
_s = it.get_utf8().value.to_string();
57+
}
4358
}
59+
60+
// std::cout << _x << std::endl;
61+
}
62+
63+
void bson_encoding::teardown() {
64+
std::cout << _x << std::endl;
4465
}
4566
}

benchmark/composite_score.hpp

-11
This file was deleted.

benchmark/main.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2017 MongoDB Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <iostream>
16+
17+
#include "benchmark_runner.hpp"
18+
19+
using namespace benchmark;
20+
21+
int main() {
22+
benchmark_runner runner;
23+
runner.run_microbenches();
24+
25+
std::cout << "BSONBench: " << runner.calculate_bson_bench_score() << " MB/s" << std::endl;
26+
std::cout << "SingleBench: " << runner.calculate_single_bench_score() << " MB/s" << std::endl;
27+
std::cout << "MultiBench: " << runner.calculate_multi_bench_score() << "MB/s" << std::endl;
28+
std::cout << "ParallelBench: " << runner.calculate_parallel_bench_score() << "MB/s"
29+
<< std::endl;
30+
std::cout << "ReadBench: " << runner.calculate_read_bench_score() << "MB/s" << std::endl;
31+
std::cout << "WriteBench: " << runner.calculate_write_bench_score() << "MB/s" << std::endl;
32+
std::cout << "DriverBench: " << runner.calculate_driver_bench_score() << "MB/s" << std::endl;
33+
}

0 commit comments

Comments
 (0)