Skip to content

Commit 720cdf5

Browse files
authoredJan 2, 2025
CSHARP-5203: Benchmark Collection and Client bulkWrite (#1550)
1 parent 8612d62 commit 720cdf5

File tree

8 files changed

+159
-24
lines changed

8 files changed

+159
-24
lines changed
 

‎benchmarks/MongoDB.Driver.Benchmarks/BenchmarkResult.cs

+7-4
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,24 @@ public sealed class BenchmarkResult
2727

2828
public BenchmarkResult(BenchmarkReport benchmarkReport)
2929
{
30+
Categories = new HashSet<string>(benchmarkReport.BenchmarkCase.Descriptor.Categories);
31+
3032
int dataSetSize;
31-
if (benchmarkReport.BenchmarkCase.Descriptor.HasCategory(DriverBenchmarkCategory.BsonBench))
33+
if (Categories.Contains(DriverBenchmarkCategory.BsonBench))
3234
{
3335
var bsonBenchmarkData = (BsonBenchmarkData)benchmarkReport.BenchmarkCase.Parameters["BenchmarkData"];
3436
Name = bsonBenchmarkData.DataSetName + benchmarkReport.BenchmarkCase.Descriptor.Type.Name;
3537
dataSetSize = bsonBenchmarkData.DataSetSize;
3638
}
3739
else
3840
{
39-
Name = benchmarkReport.BenchmarkCase.Descriptor.Type.Name;
41+
Name = Categories.Contains(DriverBenchmarkCategory.BulkWriteBench)
42+
? benchmarkReport.BenchmarkCase.Descriptor.WorkloadMethod.Name
43+
: benchmarkReport.BenchmarkCase.Descriptor.Type.Name;
44+
4045
dataSetSize = (int)benchmarkReport.BenchmarkCase.Parameters["BenchmarkDataSetSize"];
4146
}
4247

43-
Categories = new HashSet<string>(benchmarkReport.BenchmarkCase.Descriptor.Categories);
44-
4548
// change the median from nanoseconds to seconds for calculating the score.
4649
// since dataSetSize is in bytes, divide the score to convert to MB/s
4750
Score = (dataSetSize / (benchmarkReport.ResultStatistics.Median / 1_000_000_000D)) / 1_000_000D;

‎benchmarks/MongoDB.Driver.Benchmarks/DriverBenchmarkCategory.cs

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ public static class DriverBenchmarkCategory
2626
public const string ReadBench = "ReadBench";
2727
public const string SingleBench = "SingleBench";
2828
public const string WriteBench = "WriteBench";
29+
30+
// not included in AllCategories as it's not part of the benchmarking spec
31+
public const string BulkWriteBench = "BulkWriteBench";
2932

3033
public static readonly IEnumerable<string> AllCategories = new[] {BsonBench, ReadBench, WriteBench, MultiBench, SingleBench, ParallelBench, DriverBench};
3134
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* Copyright 2010-present 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+
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using BenchmarkDotNet.Attributes;
19+
using MongoDB.Bson;
20+
using MongoDB.Driver;
21+
using static MongoDB.Benchmarks.BenchmarkHelper;
22+
23+
namespace MongoDB.Benchmarks.MultiDoc
24+
{
25+
[IterationCount(15)]
26+
[BenchmarkCategory(DriverBenchmarkCategory.BulkWriteBench, DriverBenchmarkCategory.MultiBench, DriverBenchmarkCategory.WriteBench, DriverBenchmarkCategory.DriverBench)]
27+
public class BulkWriteMixedOpsBenchmark
28+
{
29+
private IMongoClient _client;
30+
private IMongoCollection<BsonDocument> _collection;
31+
private IMongoDatabase _database;
32+
private readonly List<BulkWriteModel> _clientBulkWriteMixedOpsModels = [];
33+
private readonly List<WriteModel<BsonDocument>> _collectionBulkWriteMixedOpsModels = [];
34+
35+
private static readonly string[] __collectionNamespaces = Enumerable.Range(0, 10)
36+
.Select(i => $"{MongoConfiguration.PerfTestDatabaseName}.{MongoConfiguration.PerfTestCollectionName}_{i}")
37+
.ToArray();
38+
39+
[Params(5_500_000)]
40+
public int BenchmarkDataSetSize { get; set; } // used in BenchmarkResult.cs
41+
42+
[GlobalSetup]
43+
public void Setup()
44+
{
45+
_client = MongoConfiguration.CreateClient();
46+
47+
var smallDocument = ReadExtendedJson("single_and_multi_document/small_doc.json");
48+
for (var i = 0; i < 10000; i++)
49+
{
50+
var collectionName = __collectionNamespaces[i % __collectionNamespaces.Length];
51+
52+
_clientBulkWriteMixedOpsModels.Add(new BulkWriteInsertOneModel<BsonDocument>(collectionName, smallDocument.DeepClone().AsBsonDocument));
53+
_clientBulkWriteMixedOpsModels.Add(new BulkWriteReplaceOneModel<BsonDocument>(collectionName, FilterDefinition<BsonDocument>.Empty, smallDocument.DeepClone().AsBsonDocument));
54+
_clientBulkWriteMixedOpsModels.Add(new BulkWriteDeleteOneModel<BsonDocument>(collectionName, FilterDefinition<BsonDocument>.Empty));
55+
56+
_collectionBulkWriteMixedOpsModels.Add(new InsertOneModel<BsonDocument>(smallDocument.DeepClone().AsBsonDocument));
57+
_collectionBulkWriteMixedOpsModels.Add(new ReplaceOneModel<BsonDocument>(FilterDefinition<BsonDocument>.Empty, smallDocument.DeepClone().AsBsonDocument));
58+
_collectionBulkWriteMixedOpsModels.Add(new DeleteOneModel<BsonDocument>(FilterDefinition<BsonDocument>.Empty));
59+
}
60+
}
61+
62+
[IterationSetup]
63+
public void BeforeTask()
64+
{
65+
_client.DropDatabase(MongoConfiguration.PerfTestDatabaseName);
66+
67+
_database = _client.GetDatabase(MongoConfiguration.PerfTestDatabaseName);
68+
foreach (var collectionName in __collectionNamespaces)
69+
{
70+
_database.CreateCollection(collectionName.Split('.')[1]);
71+
}
72+
73+
_collection = _database.GetCollection<BsonDocument>(MongoConfiguration.PerfTestCollectionName);
74+
}
75+
76+
[Benchmark]
77+
public void SmallDocCollectionBulkWriteMixedOpsBenchmark()
78+
{
79+
_collection.BulkWrite(_collectionBulkWriteMixedOpsModels, new());
80+
}
81+
82+
[Benchmark]
83+
public void SmallDocClientBulkWriteMixedOpsBenchmark()
84+
{
85+
_client.BulkWrite(_clientBulkWriteMixedOpsModels, new());
86+
}
87+
88+
[GlobalCleanup]
89+
public void Teardown()
90+
{
91+
_client.Dispose();
92+
}
93+
}
94+
}

‎benchmarks/MongoDB.Driver.Benchmarks/MultiDoc/InsertManyLargeBenchmark.cs renamed to ‎benchmarks/MongoDB.Driver.Benchmarks/MultiDoc/LargeDocBulkInsertBenchmark.cs

+25-7
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@
1818
using BenchmarkDotNet.Attributes;
1919
using MongoDB.Bson;
2020
using MongoDB.Driver;
21-
using MongoDB.Driver.TestHelpers;
2221
using static MongoDB.Benchmarks.BenchmarkHelper;
2322

2423
namespace MongoDB.Benchmarks.MultiDoc
2524
{
2625
[IterationCount(100)]
27-
[BenchmarkCategory(DriverBenchmarkCategory.MultiBench, DriverBenchmarkCategory.WriteBench, DriverBenchmarkCategory.DriverBench)]
28-
public class InsertManyLargeBenchmark
26+
[BenchmarkCategory(DriverBenchmarkCategory.BulkWriteBench, DriverBenchmarkCategory.MultiBench, DriverBenchmarkCategory.WriteBench, DriverBenchmarkCategory.DriverBench)]
27+
public class LargeDocBulkInsertBenchmark
2928
{
3029
private IMongoClient _client;
3130
private IMongoCollection<BsonDocument> _collection;
3231
private IMongoDatabase _database;
33-
private IEnumerable<BsonDocument> _largeDocuments;
32+
private BsonDocument[] _largeDocuments;
33+
private InsertOneModel<BsonDocument>[] _collectionBulkWriteInsertModels;
34+
private BulkWriteInsertOneModel<BsonDocument>[] _clientBulkWriteInsertModels;
35+
36+
private static readonly CollectionNamespace __collectionNamespace =
37+
CollectionNamespace.FromFullName($"{MongoConfiguration.PerfTestDatabaseName}.{MongoConfiguration.PerfTestCollectionName}");
3438

3539
[Params(27_310_890)]
3640
public int BenchmarkDataSetSize { get; set; } // used in BenchmarkResult.cs
@@ -42,7 +46,9 @@ public void Setup()
4246
_database = _client.GetDatabase(MongoConfiguration.PerfTestDatabaseName);
4347

4448
var largeDocument = ReadExtendedJson("single_and_multi_document/large_doc.json");
45-
_largeDocuments = Enumerable.Range(0, 10).Select(_ => largeDocument.DeepClone().AsBsonDocument);
49+
_largeDocuments = Enumerable.Range(0, 10).Select(_ => largeDocument.DeepClone().AsBsonDocument).ToArray();
50+
_collectionBulkWriteInsertModels = _largeDocuments.Select(x => new InsertOneModel<BsonDocument>(x.DeepClone().AsBsonDocument)).ToArray();
51+
_clientBulkWriteInsertModels = _largeDocuments.Select(x => new BulkWriteInsertOneModel<BsonDocument>(__collectionNamespace, x.DeepClone().AsBsonDocument)).ToArray();
4652
}
4753

4854
[IterationSetup]
@@ -53,9 +59,21 @@ public void BeforeTask()
5359
}
5460

5561
[Benchmark]
56-
public void InsertManyLarge()
62+
public void InsertManyLargeBenchmark()
5763
{
58-
_collection.InsertMany(_largeDocuments, new InsertManyOptions());
64+
_collection.InsertMany(_largeDocuments, new());
65+
}
66+
67+
[Benchmark]
68+
public void LargeDocCollectionBulkWriteInsertBenchmark()
69+
{
70+
_collection.BulkWrite(_collectionBulkWriteInsertModels, new());
71+
}
72+
73+
[Benchmark]
74+
public void LargeDocClientBulkWriteInsertBenchmark()
75+
{
76+
_client.BulkWrite(_clientBulkWriteInsertModels, new());
5977
}
6078

6179
[GlobalCleanup]

‎benchmarks/MongoDB.Driver.Benchmarks/MultiDoc/InsertManySmallBenchmark.cs renamed to ‎benchmarks/MongoDB.Driver.Benchmarks/MultiDoc/SmallDocBulkInsertBenchmark.cs

+25-8
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@
1313
* limitations under the License.
1414
*/
1515

16-
using System.Collections.Generic;
1716
using System.Linq;
1817
using BenchmarkDotNet.Attributes;
1918
using MongoDB.Bson;
2019
using MongoDB.Driver;
21-
using MongoDB.Driver.TestHelpers;
2220
using static MongoDB.Benchmarks.BenchmarkHelper;
2321

2422
namespace MongoDB.Benchmarks.MultiDoc
2523
{
2624
[IterationCount(100)]
27-
[BenchmarkCategory(DriverBenchmarkCategory.MultiBench, DriverBenchmarkCategory.WriteBench, DriverBenchmarkCategory.DriverBench)]
28-
public class InsertManySmallBenchmark
25+
[BenchmarkCategory(DriverBenchmarkCategory.BulkWriteBench, DriverBenchmarkCategory.MultiBench, DriverBenchmarkCategory.WriteBench, DriverBenchmarkCategory.DriverBench)]
26+
public class SmallDocBulkInsertBenchmark
2927
{
3028
private IMongoClient _client;
3129
private IMongoCollection<BsonDocument> _collection;
3230
private IMongoDatabase _database;
33-
private IEnumerable<BsonDocument> _smallDocuments;
31+
private BsonDocument[] _smallDocuments;
32+
private InsertOneModel<BsonDocument>[] _collectionBulkWriteInsertModels;
33+
private BulkWriteInsertOneModel<BsonDocument>[] _clientBulkWriteInsertModels;
34+
35+
private static readonly CollectionNamespace __collectionNamespace =
36+
CollectionNamespace.FromFullName($"{MongoConfiguration.PerfTestDatabaseName}.{MongoConfiguration.PerfTestCollectionName}");
3437

3538
[Params(2_750_000)]
3639
public int BenchmarkDataSetSize { get; set; } // used in BenchmarkResult.cs
@@ -42,7 +45,9 @@ public void Setup()
4245
_database = _client.GetDatabase(MongoConfiguration.PerfTestDatabaseName);
4346

4447
var smallDocument = ReadExtendedJson("single_and_multi_document/small_doc.json");
45-
_smallDocuments = Enumerable.Range(0, 10000).Select(_ => smallDocument.DeepClone().AsBsonDocument);
48+
_smallDocuments = Enumerable.Range(0, 10000).Select(_ => smallDocument.DeepClone().AsBsonDocument).ToArray();
49+
_collectionBulkWriteInsertModels = _smallDocuments.Select(x => new InsertOneModel<BsonDocument>(x.DeepClone().AsBsonDocument)).ToArray();
50+
_clientBulkWriteInsertModels = _smallDocuments.Select(x => new BulkWriteInsertOneModel<BsonDocument>(__collectionNamespace, x.DeepClone().AsBsonDocument)).ToArray();
4651
}
4752

4853
[IterationSetup]
@@ -53,9 +58,21 @@ public void BeforeTask()
5358
}
5459

5560
[Benchmark]
56-
public void InsertManySmall()
61+
public void InsertManySmallBenchmark()
62+
{
63+
_collection.InsertMany(_smallDocuments, new());
64+
}
65+
66+
[Benchmark]
67+
public void SmallDocCollectionBulkWriteInsertBenchmark()
68+
{
69+
_collection.BulkWrite(_collectionBulkWriteInsertModels, new());
70+
}
71+
72+
[Benchmark]
73+
public void SmallDocClientBulkWriteInsertBenchmark()
5774
{
58-
_collection.InsertMany(_smallDocuments, new InsertManyOptions());
75+
_client.BulkWrite(_clientBulkWriteInsertModels, new());
5976
}
6077

6178
[GlobalCleanup]

‎benchmarks/MongoDB.Driver.Benchmarks/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This suite implements the benchmarks described in this [spec](https://github.com
1313
(e.g `dotnet run -c Release -- --driverBenchmarks --envVars MONGODB_URI:"ConnectionString"`)
1414

1515
You can also select the benchmarks to run directly on the command for running the benchmarks as such
16-
`dotnet run -c Release -- --driverBenchmarks --fitler "*BenchmarkClassName*"`. The benchmarks are also grouped into categories namely: BSONBench, WriteBench
16+
`dotnet run -c Release -- --driverBenchmarks --filter "*BenchmarkClassName*"`. The benchmarks are also grouped into categories namely: BSONBench, WriteBench
1717
ReadBench, ParallelBench, SingleBench, MultiBench and DriverBench. So if you wanted to only run the WriteBench benchmarks, you can do so
1818
as follows: `dotnet run -c Release -- --driverBenchmarks --anyCategories "WriteBench"`.
1919

‎benchmarks/MongoDB.Driver.Benchmarks/scripts/download-data.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/sh
1+
#!/usr/bin/env bash
22

33
# Copyright 2010 MongoDB, Inc.
44
#

‎evergreen/evergreen.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1503,11 +1503,11 @@ tasks:
15031503
- func: bootstrap-mongo-orchestration
15041504
- func: run-smoke-tests
15051505

1506-
- name: performance-tests-net80-server-v6.0
1506+
- name: test-csharp-spec-benchmarks
15071507
commands:
15081508
- func: bootstrap-mongo-orchestration
15091509
vars:
1510-
VERSION: "v6.0-perf"
1510+
VERSION: "v8.0-perf"
15111511
TOPOLOGY: "server"
15121512
SSL: "nossl"
15131513
AUTH: "noauth"
@@ -2604,7 +2604,7 @@ buildvariants:
26042604
run_on:
26052605
- rhel90-dbx-perf-large
26062606
tasks:
2607-
- name: performance-tests-net80-server-v6.0
2607+
- name: test-csharp-spec-benchmarks
26082608

26092609
# AWS Lambda tests
26102610
- name: aws-lambda-tests

0 commit comments

Comments
 (0)
Please sign in to comment.