Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dbe9d8b

Browse filesBrowse files
feat: Add micro-benchmarks for writes comparing standard (regional) vs rapid (zonal) buckets. (#1707)
* Add performance microbenchmarking suite for Writes * This compares Regional (Standard Storage) with Zonal (Rapid Storage) buckets. * Regional uses JSON wheres Zonal uses gRPC bidi --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 1917649 commit dbe9d8b
Copy full SHA for dbe9d8b

File tree

Expand file treeCollapse file tree

7 files changed

+585
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+585
-7
lines changed
Open diff view settings
Collapse file

‎tests/perf/microbenchmarks/README.md‎

Copy file name to clipboardExpand all lines: tests/perf/microbenchmarks/README.md
+4-1Lines changed: 4 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ pytest --benchmark-json=output.json -vv -s tests/perf/microbenchmarks/reads/test
1515

1616
To run a single test, append `::` followed by the test name to the file path.
1717

18-
Example:
18+
Examples:
1919
```bash
2020
pytest --benchmark-json=output.json -vv -s tests/perf/microbenchmarks/reads/test_reads.py::test_downloads_single_proc_single_coro
2121
```
22+
```bash
23+
pytest --benchmark-json=output.json -vv -s tests/perf/microbenchmarks/writes/test_writes.py::test_uploads_single_proc_single_coro
24+
```
2225

2326
## Configuration
2427

Collapse file

‎tests/perf/microbenchmarks/conftest.py‎

Copy file name to clipboardExpand all lines: tests/perf/microbenchmarks/conftest.py
+13-6Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
AsyncAppendableObjectWriter,
2727
)
2828
from google.cloud.storage._experimental.asyncio.async_grpc_client import AsyncGrpcClient
29+
from tests.perf.microbenchmarks.writes.parameters import WriteParameters
2930

3031
_OBJECT_NAME_PREFIX = "micro-benchmark"
3132

@@ -135,10 +136,16 @@ def _create_files(num_files, bucket_name, bucket_type, object_size, chunk_size=1
135136
@pytest.fixture
136137
def workload_params(request):
137138
params = request.param
138-
files_names = _create_files(
139-
params.num_files,
140-
params.bucket_name,
141-
params.bucket_type,
142-
params.file_size_bytes,
143-
)
139+
if isinstance(params, WriteParameters):
140+
files_names = [
141+
f"{_OBJECT_NAME_PREFIX}-{uuid.uuid4().hex[:5]}"
142+
for _ in range(params.num_files)
143+
]
144+
else:
145+
files_names = _create_files(
146+
params.num_files,
147+
params.bucket_name,
148+
params.bucket_type,
149+
params.file_size_bytes,
150+
)
144151
return params, files_names
Collapse file

‎tests/perf/microbenchmarks/writes/__init__.py‎

Copy file name to clipboardExpand all lines: tests/perf/microbenchmarks/writes/__init__.py
Whitespace-only changes.
Collapse file
+100Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Copyright 2026 Google LLC
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+
import itertools
15+
import os
16+
from typing import Dict, List
17+
18+
import yaml
19+
20+
try:
21+
from tests.perf.microbenchmarks.writes.parameters import WriteParameters
22+
except ModuleNotFoundError:
23+
from parameters import WriteParameters
24+
25+
26+
def get_write_params() -> Dict[str, List[WriteParameters]]:
27+
"""Generates benchmark parameters from a YAML configuration file.
28+
29+
This function reads the configuration from `config.yaml`, located in the
30+
same directory, and generates all possible combinations of write parameters
31+
based on the defined workloads. It uses `itertools.product` to create
32+
a Cartesian product of parameters like bucket types, file sizes, etc.
33+
34+
Returns:
35+
Dict[str, List[WriteParameters]]: A dictionary where keys are workload
36+
names and values are lists of `WriteParameters` instances for that
37+
workload.
38+
"""
39+
params: Dict[str, List[WriteParameters]] = {}
40+
config_path = os.path.join(os.path.dirname(__file__), "config.yaml")
41+
with open(config_path, "r") as f:
42+
config = yaml.safe_load(f)
43+
44+
common_params = config["common"]
45+
bucket_types = common_params["bucket_types"]
46+
file_sizes_mib = common_params["file_sizes_mib"]
47+
chunk_sizes_mib = common_params["chunk_sizes_mib"]
48+
rounds = common_params["rounds"]
49+
50+
bucket_map = {
51+
"zonal": os.environ.get("DEFAULT_RAPID_ZONAL_BUCKET", config['defaults']['DEFAULT_RAPID_ZONAL_BUCKET']),
52+
"regional": os.environ.get("DEFAULT_STANDARD_BUCKET", config['defaults']['DEFAULT_STANDARD_BUCKET'])
53+
}
54+
55+
for workload in config["workload"]:
56+
workload_name = workload["name"]
57+
params[workload_name] = []
58+
processes = workload["processes"]
59+
coros = workload["coros"]
60+
61+
# Create a product of all parameter combinations
62+
product = itertools.product(
63+
bucket_types,
64+
file_sizes_mib,
65+
chunk_sizes_mib,
66+
processes,
67+
coros,
68+
)
69+
70+
for (
71+
bucket_type,
72+
file_size_mib,
73+
chunk_size_mib,
74+
num_processes,
75+
num_coros,
76+
) in product:
77+
file_size_bytes = file_size_mib * 1024 * 1024
78+
chunk_size_bytes = chunk_size_mib * 1024 * 1024
79+
bucket_name = bucket_map[bucket_type]
80+
81+
num_files = num_processes * num_coros
82+
83+
# Create a descriptive name for the parameter set
84+
name = f"{workload_name}_{bucket_type}_{num_processes}p_{num_coros}c"
85+
86+
params[workload_name].append(
87+
WriteParameters(
88+
name=name,
89+
workload_name=workload_name,
90+
bucket_name=bucket_name,
91+
bucket_type=bucket_type,
92+
num_coros=num_coros,
93+
num_processes=num_processes,
94+
num_files=num_files,
95+
rounds=rounds,
96+
chunk_size_bytes=chunk_size_bytes,
97+
file_size_bytes=file_size_bytes,
98+
)
99+
)
100+
return params
Collapse file
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
common:
2+
bucket_types:
3+
- "regional"
4+
- "zonal"
5+
file_sizes_mib:
6+
- 1024 # 1GiB
7+
chunk_sizes_mib: [100]
8+
rounds: 10
9+
10+
workload:
11+
12+
############# single proc single coroutines #########
13+
- name: "write_seq"
14+
pattern: "seq"
15+
coros: [1]
16+
processes: [1]
17+
18+
############# single proc multiple coroutines #########
19+
20+
- name: "write_seq_multi_coros"
21+
pattern: "seq"
22+
coros: [2, 4, 8, 16]
23+
processes: [1]
24+
25+
############# multiple proc multiple coroutines #########
26+
- name: "write_seq_multi_process"
27+
pattern: "seq"
28+
coros: [1, 2]
29+
processes: [8, 16, 32, 64]
30+
31+
32+
defaults:
33+
DEFAULT_RAPID_ZONAL_BUCKET: "chandrasiri-benchmarks-zb"
34+
DEFAULT_STANDARD_BUCKET: "chandrasiri-benchmarks-rb"
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright 2026 Google LLC
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+
from dataclasses import dataclass
15+
from ..parameters import IOBenchmarkParameters
16+
17+
18+
@dataclass
19+
class WriteParameters(IOBenchmarkParameters):
20+
pass

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.