Skip to content

Commit fa9384e

Browse files
committed
Merge pull request #742 from estolfo/benchmarking-1
Driver Benchmark tests
2 parents 4d10741 + 1a9b6fb commit fa9384e

File tree

8 files changed

+1013
-0
lines changed

8 files changed

+1013
-0
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ group :development, :testing do
1010
gem 'rspec', '~> 3.0'
1111
gem 'mime-types', '~> 1.25'
1212
gem 'httparty'
13+
gem 'yajl-ruby', require: 'yajl', platforms: :mri
14+
gem 'celluloid', platforms: :mri
1315
end
1416

1517
group :development do

Rakefile

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,158 @@ namespace :docs do
4141
system "yardoc -o #{out} --title mongo-#{Mongo::VERSION}"
4242
end
4343
end
44+
45+
require_relative "profile/benchmarking"
46+
47+
# Some require data files, available from the drivers team. See the comments above each task for details."
48+
namespace :benchmark do
49+
desc "Run the driver benchmark tests."
50+
51+
namespace :micro do
52+
desc "Run the common driver micro benchmarking tests"
53+
54+
namespace :flat do
55+
desc "Benchmarking for flat bson documents."
56+
57+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called flat_bson.json.
58+
task :encode do
59+
puts "MICRO BENCHMARK:: FLAT:: ENCODE"
60+
Mongo::Benchmarking::Micro.run(:flat, :encode)
61+
end
62+
63+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called flat_bson.json.
64+
task :decode do
65+
puts "MICRO BENCHMARK:: FLAT:: DECODE"
66+
Mongo::Benchmarking::Micro.run(:flat, :decode)
67+
end
68+
end
69+
70+
namespace :deep do
71+
desc "Benchmarking for deep bson documents."
72+
73+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called deep_bson.json.
74+
task :encode do
75+
puts "MICRO BENCHMARK:: DEEP:: ENCODE"
76+
Mongo::Benchmarking::Micro.run(:deep, :encode)
77+
end
78+
79+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called deep_bson.json.
80+
task :decode do
81+
puts "MICRO BENCHMARK:: DEEP:: DECODE"
82+
Mongo::Benchmarking::Micro.run(:deep, :decode)
83+
end
84+
end
85+
86+
namespace :full do
87+
desc "Benchmarking for full bson documents."
88+
89+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called full_bson.json.
90+
task :encode do
91+
puts "MICRO BENCHMARK:: FULL:: ENCODE"
92+
Mongo::Benchmarking::Micro.run(:full, :encode)
93+
end
94+
95+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called full_bson.json.
96+
task :decode do
97+
puts "MICRO BENCHMARK:: FULL:: DECODE"
98+
Mongo::Benchmarking::Micro.run(:full, :decode)
99+
end
100+
end
101+
end
102+
103+
namespace :single_doc do
104+
desc "Run the common driver single-document benchmarking tests"
105+
task :command do
106+
puts "SINGLE DOC BENCHMARK:: COMMAND"
107+
Mongo::Benchmarking::SingleDoc.run(:command)
108+
end
109+
110+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called TWEET.json.
111+
task :find_one do
112+
puts "SINGLE DOC BENCHMARK:: FIND ONE BY ID"
113+
Mongo::Benchmarking::SingleDoc.run(:find_one)
114+
end
115+
116+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called SMALL_DOC.json.
117+
task :insert_one_small do
118+
puts "SINGLE DOC BENCHMARK:: INSERT ONE SMALL DOCUMENT"
119+
Mongo::Benchmarking::SingleDoc.run(:insert_one_small)
120+
end
121+
122+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called LARGE_DOC.json.
123+
task :insert_one_large do
124+
puts "SINGLE DOC BENCHMARK:: INSERT ONE LARGE DOCUMENT"
125+
Mongo::Benchmarking::SingleDoc.run(:insert_one_large)
126+
end
127+
end
128+
129+
namespace :multi_doc do
130+
desc "Run the common driver multi-document benchmarking tests"
131+
132+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called TWEET.json.
133+
task :find_many do
134+
puts "MULTI DOCUMENT BENCHMARK:: FIND MANY"
135+
Mongo::Benchmarking::MultiDoc.run(:find_many)
136+
end
137+
138+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called SMALL_DOC.json.
139+
task :bulk_insert_small do
140+
puts "MULTI DOCUMENT BENCHMARK:: BULK INSERT SMALL"
141+
Mongo::Benchmarking::MultiDoc.run(:bulk_insert_small)
142+
end
143+
144+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called LARGE_DOC.json.
145+
task :bulk_insert_large do
146+
puts "MULTI DOCUMENT BENCHMARK:: BULK INSERT LARGE"
147+
Mongo::Benchmarking::MultiDoc.run(:bulk_insert_large)
148+
end
149+
150+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called GRIDFS_LARGE.
151+
task :gridfs_upload do
152+
puts "MULTI DOCUMENT BENCHMARK:: GRIDFS UPLOAD"
153+
Mongo::Benchmarking::MultiDoc.run(:gridfs_upload)
154+
end
155+
156+
# Requirement: A file in Mongo::Benchmarking::DATA_PATH, called GRIDFS_LARGE.
157+
task :gridfs_download do
158+
puts "MULTI DOCUMENT BENCHMARK:: GRIDFS DOWNLOAD"
159+
Mongo::Benchmarking::MultiDoc.run(:gridfs_download)
160+
end
161+
end
162+
163+
namespace :parallel do
164+
desc "Run the common driver paralell ETL benchmarking tests"
165+
166+
# Requirement: A directory in Mongo::Benchmarking::DATA_PATH, called LDJSON_MULTI,
167+
# with the files used in this task.
168+
task :import do
169+
puts "PARALLEL ETL BENCHMARK:: IMPORT"
170+
Mongo::Benchmarking::Parallel.run(:import)
171+
end
172+
173+
# Requirement: A directory in Mongo::Benchmarking::DATA_PATH, called LDJSON_MULTI,
174+
# with the files used in this task.
175+
# Requirement: Another directory in "#{Mongo::Benchmarking::DATA_PATH}/LDJSON_MULTI"
176+
# called 'output'.
177+
task :export do
178+
puts "PARALLEL ETL BENCHMARK:: EXPORT"
179+
Mongo::Benchmarking::Parallel.run(:export)
180+
end
181+
182+
# Requirement: A directory in Mongo::Benchmarking::DATA_PATH, called GRIDFS_MULTI,
183+
# with the files used in this task.
184+
task :gridfs_upload do
185+
puts "PARALLEL ETL BENCHMARK:: GRIDFS UPLOAD"
186+
Mongo::Benchmarking::Parallel.run(:gridfs_upload)
187+
end
188+
189+
# Requirement: A directory in Mongo::Benchmarking::DATA_PATH, called GRIDFS_MULTI,
190+
# with the files used in this task.
191+
# Requirement: Another directory in "#{Mongo::Benchmarking::DATA_PATH}/GRIDFS_MULTI"
192+
# called 'output'.
193+
task :gridfs_download do
194+
puts "PARALLEL ETL BENCHMARK:: GRIDFS DOWNLOAD"
195+
Mongo::Benchmarking::Parallel.run(:gridfs_download)
196+
end
197+
end
198+
end

profile/benchmarking.rb

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Copyright (C) 2015 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+
require 'benchmark'
16+
require_relative 'benchmarking/helper'
17+
require_relative 'benchmarking/micro'
18+
require_relative 'benchmarking/single_doc'
19+
require_relative 'benchmarking/multi_doc'
20+
require_relative 'benchmarking/parallel'
21+
22+
module Mongo
23+
24+
# Module with all functionality for running driver benchmark tests.
25+
#
26+
# @since 2.2.3
27+
module Benchmarking
28+
29+
extend self
30+
31+
# The current path.
32+
#
33+
# @return [ String ] The current path.
34+
#
35+
# @since 2.2.3
36+
CURRENT_PATH = File.expand_path(File.dirname(__FILE__)).freeze
37+
38+
# The path to data files used in Benchmarking tests.
39+
#
40+
# @return [ String ] Path to Benchmarking test files.
41+
#
42+
# @since 2.2.3
43+
DATA_PATH = [CURRENT_PATH, 'benchmarking', 'data'].join('/').freeze
44+
45+
# The file containing the single tweet document.
46+
#
47+
# @return [ String ] The file containing the tweet document.
48+
#
49+
# @since 2.2.3
50+
TWEET_DOCUMENT_FILE = [DATA_PATH, 'TWEET.json'].join('/').freeze
51+
52+
# The file containing the single small document.
53+
#
54+
# @return [ String ] The file containing the small document.
55+
#
56+
# @since 2.2.3
57+
SMALL_DOCUMENT_FILE = [DATA_PATH, 'SMALL_DOC.json'].join('/').freeze
58+
59+
# The file containing the single large document.
60+
#
61+
# @return [ String ] The file containing the large document.
62+
#
63+
# @since 2.2.3
64+
LARGE_DOCUMENT_FILE = [DATA_PATH, 'LARGE_DOC.json'].join('/').freeze
65+
66+
# The file to upload when testing GridFS.
67+
#
68+
# @return [ String ] The file containing the GridFS test data.
69+
#
70+
# @since 2.2.3
71+
GRIDFS_FILE = [DATA_PATH, 'GRIDFS_LARGE'].join('/').freeze
72+
73+
# The file path and base name for the LDJSON files.
74+
#
75+
# @return [ String ] The file path and base name for the LDJSON files.
76+
#
77+
# @since 2.2.3
78+
LDJSON_FILE_BASE = [DATA_PATH, 'LDJSON_MULTI', 'LDJSON'].join('/').freeze
79+
80+
# The file path and base name for the outputted LDJSON files.
81+
#
82+
# @return [ String ] The file path and base name for the outputted LDJSON files.
83+
#
84+
# @since 2.2.3
85+
LDJSON_FILE_OUTPUT_BASE = [DATA_PATH, 'LDJSON_MULTI', 'output', 'LDJSON'].join('/').freeze
86+
87+
# The file path and base name for the GRIDFS files to upload.
88+
#
89+
# @return [ String ] The file path and base name for the GRIDFS files to upload.
90+
#
91+
# @since 2.2.3
92+
GRIDFS_MULTI_BASE = [DATA_PATH, 'GRIDFS_MULTI', 'file'].join('/').freeze
93+
94+
# The file path and base name for the outputted GRIDFS downloaded files.
95+
#
96+
# @return [ String ] The file path and base name for the outputted GRIDFS downloaded files.
97+
#
98+
# @since 2.2.3
99+
GRIDFS_MULTI_OUTPUT_BASE = [DATA_PATH, 'GRIDFS_MULTI', 'output', 'file-output'].join('/').freeze
100+
101+
# The default number of test repetitions.
102+
#
103+
# @return [ Integer ] The number of test repetitions.
104+
#
105+
# @since 2.2.3
106+
TEST_REPETITIONS = 100.freeze
107+
108+
# The number of default warmup repetitions of the test to do before
109+
# recording times.
110+
#
111+
# @return [ Integer ] The default number of warmup repetitions.
112+
#
113+
# @since 2.2.3
114+
WARMUP_REPETITIONS = 10.freeze
115+
116+
def tweet_document
117+
Benchmarking.load_file(TWEET_DOCUMENT_FILE).first
118+
end
119+
120+
def small_document
121+
Benchmarking.load_file(SMALL_DOCUMENT_FILE).first
122+
end
123+
124+
def large_document
125+
Benchmarking.load_file(LARGE_DOCUMENT_FILE).first
126+
end
127+
end
128+
end

profile/benchmarking/helper.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module Mongo
2+
3+
# Helper functions used by benchmarking tasks
4+
module Benchmarking
5+
6+
extend self
7+
8+
# Load a json file and represent each document as a Hash.
9+
#
10+
# @example Load a file.
11+
# Benchmarking.load_file(file_name)
12+
#
13+
# @param [ String ] The file name.
14+
#
15+
# @return [ Array ] A list of extended-json documents.
16+
#
17+
# @since 2.2.3
18+
def load_file(file_name)
19+
File.open(file_name, "r") do |f|
20+
f.each_line.collect do |line|
21+
parse_json(line)
22+
end
23+
end
24+
end
25+
26+
# Load a json document as a Hash and convert BSON-specific types.
27+
# Replace the _id field as an BSON::ObjectId if it's represented as '$oid'.
28+
#
29+
# @example Parse a json document.
30+
# Benchmarking.parse_json(document)
31+
#
32+
# @param [ Hash ] The json document.
33+
#
34+
# @return [ Hash ] An extended-json document.
35+
#
36+
# @since 2.2.3
37+
def parse_json(document)
38+
JSON.parse(document).tap do |doc|
39+
if doc['_id'] && doc['_id']['$oid']
40+
doc['_id'] = BSON::ObjectId.from_string(doc['_id']['$oid'])
41+
end
42+
end
43+
end
44+
45+
# Get the median of values in a list.
46+
#
47+
# @example Get the median.
48+
# Benchmarking.median(values)
49+
#
50+
# @param [ Array ] The values to get the median of.
51+
#
52+
# @return [ Numeric ] The median of the list.
53+
#
54+
# @since 2.2.3
55+
def median(values)
56+
values.sort![values.size/2-1]
57+
end
58+
end
59+
end

0 commit comments

Comments
 (0)