green-bench 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- green_bench-0.2.0/LICENSE +21 -0
- green_bench-0.2.0/PKG-INFO +186 -0
- green_bench-0.2.0/README.md +143 -0
- green_bench-0.2.0/pyproject.toml +83 -0
- green_bench-0.2.0/setup.cfg +4 -0
- green_bench-0.2.0/src/green_bench/__init__.py +3 -0
- green_bench-0.2.0/src/green_bench/__main__.py +279 -0
- green_bench-0.2.0/src/green_bench/analysis.py +296 -0
- green_bench-0.2.0/src/green_bench/demo_data/nqueens/naive/nqueens.py +18 -0
- green_bench-0.2.0/src/green_bench/demo_data/nqueens/optimized/nqueens.py +20 -0
- green_bench-0.2.0/src/green_bench/environment.py +161 -0
- green_bench-0.2.0/src/green_bench/measurement.py +83 -0
- green_bench-0.2.0/src/green_bench/orchestrator.py +226 -0
- green_bench-0.2.0/src/green_bench/results.py +75 -0
- green_bench-0.2.0/src/green_bench.egg-info/PKG-INFO +186 -0
- green_bench-0.2.0/src/green_bench.egg-info/SOURCES.txt +23 -0
- green_bench-0.2.0/src/green_bench.egg-info/dependency_links.txt +1 -0
- green_bench-0.2.0/src/green_bench.egg-info/entry_points.txt +2 -0
- green_bench-0.2.0/src/green_bench.egg-info/requires.txt +16 -0
- green_bench-0.2.0/src/green_bench.egg-info/top_level.txt +1 -0
- green_bench-0.2.0/tests/test_analysis.py +89 -0
- green_bench-0.2.0/tests/test_cli.py +129 -0
- green_bench-0.2.0/tests/test_demo.py +74 -0
- green_bench-0.2.0/tests/test_nfr_observer_effect.py +58 -0
- green_bench-0.2.0/tests/test_orchestration.py +113 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jessica Draper
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: green-bench
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A CLI tool for automated, localized software energy experiments.
|
|
5
|
+
Author-email: Jessica Draper <jessicafaye.draper@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/jessicadraper/green-bench
|
|
8
|
+
Project-URL: Repository, https://github.com/jessicadraper/green-bench
|
|
9
|
+
Project-URL: Issues, https://github.com/jessicadraper/green-bench/issues
|
|
10
|
+
Keywords: green software,energy,benchmark,carbon,sustainability,energibridge
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Software Development :: Testing
|
|
24
|
+
Classifier: Topic :: System :: Benchmark
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: typer>=0.12.0
|
|
29
|
+
Requires-Dist: rich>=13.0.0
|
|
30
|
+
Requires-Dist: pandas>=2.2.0
|
|
31
|
+
Requires-Dist: numpy>=2.0.0
|
|
32
|
+
Requires-Dist: scipy>=1.12.0
|
|
33
|
+
Provides-Extra: plots
|
|
34
|
+
Requires-Dist: matplotlib>=3.8.0; extra == "plots"
|
|
35
|
+
Requires-Dist: seaborn>=0.13.0; extra == "plots"
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
38
|
+
Requires-Dist: psutil>=6.0.0; extra == "dev"
|
|
39
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
40
|
+
Requires-Dist: matplotlib>=3.8.0; extra == "dev"
|
|
41
|
+
Requires-Dist: seaborn>=0.13.0; extra == "dev"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<img src="https://raw.githubusercontent.com/jessicadraper/green-bench/main/docs/images/GreenBench_logo.png" alt="GreenBench logo" width="250">
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
# GreenBench
|
|
49
|
+
|
|
50
|
+
### Automated, localized software energy benchmarking framework _designed for developers_
|
|
51
|
+
|
|
52
|
+
**Does your latest feature branch or software optimization really make your system more energy efficient?** GreenBench measures it, repeats the measurement enough times to tell signal from noise, and gives you a statistically sound answer before your code ever reaches production.
|
|
53
|
+
|
|
54
|
+
GreenBench is a command-line framework that lets developers run energy benchmarking experiments on their own machine. It runs the same workload command against two copies of your project (a _baseline_ and a _treatment_) and alternates between them in a randomized order. It records the energy used by each run with [EnergiBridge](https://github.com/tdurieux/EnergiBridge), then reports whether the difference is statistically significant and what it means in gCO2e.
|
|
55
|
+
|
|
56
|
+
GreenBench is meant for **local development machines**. Absolute numbers are only meaningful relative to each other, so the value lies in the _comparison_.
|
|
57
|
+
|
|
58
|
+
> New to this? Start with the [basic intro](https://github.com/jessicadraper/green-bench/blob/main/docs/getting-started.md).
|
|
59
|
+
> Want the details? See the [user guide](https://github.com/jessicadraper/green-bench/blob/main/docs/user-guide.md).
|
|
60
|
+
|
|
61
|
+
## Why GreenBench?
|
|
62
|
+
|
|
63
|
+
The electricity consumption of data centers is rising quickly, driven by cloud computing and AI. Every application deployed to that infrastructure contributes to its footprint. Yet developers have few practical ways to see how their own design decisions affect energy use.
|
|
64
|
+
|
|
65
|
+
- **Cloud carbon dashboards arrive too late.** Cloud providers such as AWS and Azure offer emissions dashboards and reports, but only after the software has been deployed and run. Those emissions have already been spent.
|
|
66
|
+
- **They are also too coarse.** Dashboards estimate emissions per service or cluster, not per application, feature branch or design decision. They can't tell you whether the query you just rewrote helped.
|
|
67
|
+
- **Hardware power meters** are accurate, but they cost time and money to set up and are rarely available to software teams.
|
|
68
|
+
- **Software energy profilers** such as EnergiBridge make measurement accessible from the command line. On their own, though, they measure one run. A single measurement on a busy laptop is dominated by noise, and turning it into a trustworthy comparison takes repeated runs, interleaving, warm-ups, environment resets and statistical testing.
|
|
69
|
+
- **Research-grade experiment orchestrators** exist, but they are designed for academic labs rather than day-to-day development.
|
|
70
|
+
|
|
71
|
+
GreenBench closes this gap by bringing the experimental methodology used in software energy research into the place developers already work: Git branches on a local machine. This is a **"shift left"** approach to green software. Energy becomes something you can test during development, the same way you test correctness or performance, rather than something you discover on a cloud bill.
|
|
72
|
+
|
|
73
|
+
## Quickstart
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pipx install "green-bench[plots]" # or: pip install "green-bench[plots]"; drop [plots] if you don't need the charts
|
|
77
|
+
green-bench --version
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
You also need [EnergiBridge](https://github.com/tdurieux/EnergiBridge) installed. Then try the built-in example (two versions of an N-Queens solver; no project of your own needed):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
green-bench demo
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The demo copies the two example programs into `./green-bench-demo/` and **prints the exact `green-bench` command it runs**, so you can reuse it on your own project. With two directories that hold the two versions of your project, that looks like:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
green-bench \
|
|
90
|
+
--name my-experiment \
|
|
91
|
+
--base ./project-v1 \
|
|
92
|
+
--compare ./project-v2 \
|
|
93
|
+
--setup 'true' \
|
|
94
|
+
--cmd 'python workload.py' \
|
|
95
|
+
-n 30
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Results are written to `green-bench-results/my-experiment/`:
|
|
99
|
+
|
|
100
|
+
- `data.csv` (one row per run)
|
|
101
|
+
- `results.csv` (the statistics)
|
|
102
|
+
- two plots
|
|
103
|
+
- `output.log`.
|
|
104
|
+
|
|
105
|
+
## Requirements
|
|
106
|
+
|
|
107
|
+
- Python 3.10+
|
|
108
|
+
- **[EnergiBridge](https://github.com/tdurieux/EnergiBridge)** installed so that `energibridge --version` works in your terminal. It reads hardware energy counters, which usually requires elevated privileges (e.g. running the terminal with `sudo` on macOS/Linux). Follow its README for current installation instructions and supported hardware.
|
|
109
|
+
- Two directories containing the versions to compare (for example two `git clone`/`git worktree` checkouts of different branches or commits).
|
|
110
|
+
- A workload that is _computationally significant_: it should run for several seconds, not milliseconds, and do the same work every time.
|
|
111
|
+
|
|
112
|
+
## Before you measure
|
|
113
|
+
|
|
114
|
+
GreenBench measures system-wide power, so anything else your machine is doing ends up in the numbers. To reduce noise:
|
|
115
|
+
|
|
116
|
+
- Close other applications and background processes
|
|
117
|
+
- Plug into power and disable sleep
|
|
118
|
+
- Turn off Wi-Fi/Bluetooth if the workload does not need them
|
|
119
|
+
- Run from a plain terminal, not an IDE
|
|
120
|
+
- Keep the room temperature and the laptop's position consistent between sessions
|
|
121
|
+
- If you can, run your services natively rather than inside Docker Desktop, whose VM adds background CPU load
|
|
122
|
+
- Run the workload as a plain script rather than through a test runner, which adds its own overhead
|
|
123
|
+
|
|
124
|
+
## Options
|
|
125
|
+
|
|
126
|
+
| Flag | Default | Meaning |
|
|
127
|
+
| -------------------- | --------------------- | ----------------------------------------------------------------------------------- |
|
|
128
|
+
| `--name` | required | Name of the experiment (becomes the results folder; letters, digits, `.`, `_`, `-`) |
|
|
129
|
+
| `--base`, `-b` | required | Directory with the **baseline** version |
|
|
130
|
+
| `--compare`, `-c` | required | Directory with the **treatment** version |
|
|
131
|
+
| `--setup` | required | Shell command run before every measurement, _not_ measured (use `true` for none) |
|
|
132
|
+
| `--cmd` | required | Shell command to measure |
|
|
133
|
+
| `--iterations`, `-n` | `30` | Runs per version (30+ recommended; below 10 results are unreliable) |
|
|
134
|
+
| `--intensity` | `475` | Grid carbon intensity in gCO2e/kWh |
|
|
135
|
+
| `--output`, `-o` | `green-bench-results` | Where results are saved |
|
|
136
|
+
| `--seed` | random | Seed for the run order (printed at the start so you can reproduce it) |
|
|
137
|
+
| `--cooldown` | `10` | Seconds between setup and measurement |
|
|
138
|
+
| `--interval` | `500` | EnergiBridge sampling interval (ms) |
|
|
139
|
+
| `--timeout` | none | Abort any single command after this many seconds |
|
|
140
|
+
| `--keep-raw` | off | Keep every run's raw EnergiBridge CSV in `<results>/raw/` |
|
|
141
|
+
| `--resume` | off | Continue an interrupted experiment of the same name |
|
|
142
|
+
| `--overwrite` | off | Replace an existing results folder without asking (otherwise you are prompted) |
|
|
143
|
+
| `--no-plots` | off | Skip chart generation |
|
|
144
|
+
|
|
145
|
+
## How it works (short version)
|
|
146
|
+
|
|
147
|
+
1. **Pre-flight**: checks both directories and that EnergiBridge works.
|
|
148
|
+
2. **Warm-up**: runs each version once (discarded) so caches and JITs are warm.
|
|
149
|
+
3. **Experiment**: for each of _n_ blocks, runs one baseline and one treatment in **random order within the block** (_block-randomized interleaving_), so slow drifts such as heat build-up cannot favor one version. Before each run: setup command, then a cooldown.
|
|
150
|
+
4. **Analysis**: integrates power over time to get Joules, then compares the two groups with a Mann-Whitney U test, reports medians, effect size and a bootstrap confidence interval, and converts the difference to gCO2e.
|
|
151
|
+
|
|
152
|
+
A technical reference for architecture diagrams, statistics, and limitations is coming soon.
|
|
153
|
+
|
|
154
|
+
## What it found in practice (a case study)
|
|
155
|
+
|
|
156
|
+
GreenBench was validated on a real-world web application under active development: a Node.js / PostgreSQL / Redis platform for refurbished spare parts. The test workload was a bulk import that parsed, matched and imported 1,070 inventory rows. Each comparison used 30 runs per version on an Apple M1 MacBook Air.
|
|
157
|
+
|
|
158
|
+
| Comparison | Energy change | Significant? |
|
|
159
|
+
| ------------------------------------------------------------------------- | ------------- | ------------------- |
|
|
160
|
+
| Control: identical code vs. itself | −2.17% | No (p = 0.126) |
|
|
161
|
+
| Code level: refactoring long, complex methods | −3.22% | No (p = 0.105) |
|
|
162
|
+
| Logic level: Protobuf instead of JSON between services | +1.07% | No (p = 0.363) |
|
|
163
|
+
| Logic level: bulk database I/O instead of row-by-row queries | **−63.24%** | **Yes** (p < 0.001) |
|
|
164
|
+
| Architecture: microservices merged into a single-process modular monolith | **+22.46%** | **Yes** (p < 0.001) |
|
|
165
|
+
|
|
166
|
+
The control run shows that GreenBench does not report false differences when nothing has changed. The treatments show where energy is actually decided: higher-level design decisions such as data access patterns and architecture, not code cleanliness.
|
|
167
|
+
|
|
168
|
+
These results belong to one application and one workload, and yours will differ. That is the point of GreenBench: to empower developers like you to measure your own system for real impact!
|
|
169
|
+
|
|
170
|
+
## Development
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
pip install -e ".[dev]"
|
|
174
|
+
pytest -m "not integration" # no energy hardware needed
|
|
175
|
+
ruff check src tests
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
See [CONTRIBUTING.md](https://github.com/jessicadraper/green-bench/blob/main/CONTRIBUTING.md) and the [CHANGELOG.md](https://github.com/jessicadraper/green-bench/blob/main/CHANGELOG.md).
|
|
179
|
+
|
|
180
|
+
## Background and citation
|
|
181
|
+
|
|
182
|
+
GreenBench was created as part of the MSc thesis _"Evaluating the Environmental Impact of Software Design: An Empirical Analysis using Automated Software Emissions Benchmarking"_ by Jessica Draper (Software Design and Engineering, Hochschule Campus Wien, Vienna, 2026). If you use GreenBench in research, please cite it (see [CITATION.cff](https://github.com/jessicadraper/green-bench/blob/main/CITATION.cff)).
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT, see [LICENSE](https://github.com/jessicadraper/green-bench/blob/main/LICENSE).
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/jessicadraper/green-bench/main/docs/images/GreenBench_logo.png" alt="GreenBench logo" width="250">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# GreenBench
|
|
6
|
+
|
|
7
|
+
### Automated, localized software energy benchmarking framework _designed for developers_
|
|
8
|
+
|
|
9
|
+
**Does your latest feature branch or software optimization really make your system more energy efficient?** GreenBench measures it, repeats the measurement enough times to tell signal from noise, and gives you a statistically sound answer before your code ever reaches production.
|
|
10
|
+
|
|
11
|
+
GreenBench is a command-line framework that lets developers run energy benchmarking experiments on their own machine. It runs the same workload command against two copies of your project (a _baseline_ and a _treatment_) and alternates between them in a randomized order. It records the energy used by each run with [EnergiBridge](https://github.com/tdurieux/EnergiBridge), then reports whether the difference is statistically significant and what it means in gCO2e.
|
|
12
|
+
|
|
13
|
+
GreenBench is meant for **local development machines**. Absolute numbers are only meaningful relative to each other, so the value lies in the _comparison_.
|
|
14
|
+
|
|
15
|
+
> New to this? Start with the [basic intro](https://github.com/jessicadraper/green-bench/blob/main/docs/getting-started.md).
|
|
16
|
+
> Want the details? See the [user guide](https://github.com/jessicadraper/green-bench/blob/main/docs/user-guide.md).
|
|
17
|
+
|
|
18
|
+
## Why GreenBench?
|
|
19
|
+
|
|
20
|
+
The electricity consumption of data centers is rising quickly, driven by cloud computing and AI. Every application deployed to that infrastructure contributes to its footprint. Yet developers have few practical ways to see how their own design decisions affect energy use.
|
|
21
|
+
|
|
22
|
+
- **Cloud carbon dashboards arrive too late.** Cloud providers such as AWS and Azure offer emissions dashboards and reports, but only after the software has been deployed and run. Those emissions have already been spent.
|
|
23
|
+
- **They are also too coarse.** Dashboards estimate emissions per service or cluster, not per application, feature branch or design decision. They can't tell you whether the query you just rewrote helped.
|
|
24
|
+
- **Hardware power meters** are accurate, but they cost time and money to set up and are rarely available to software teams.
|
|
25
|
+
- **Software energy profilers** such as EnergiBridge make measurement accessible from the command line. On their own, though, they measure one run. A single measurement on a busy laptop is dominated by noise, and turning it into a trustworthy comparison takes repeated runs, interleaving, warm-ups, environment resets and statistical testing.
|
|
26
|
+
- **Research-grade experiment orchestrators** exist, but they are designed for academic labs rather than day-to-day development.
|
|
27
|
+
|
|
28
|
+
GreenBench closes this gap by bringing the experimental methodology used in software energy research into the place developers already work: Git branches on a local machine. This is a **"shift left"** approach to green software. Energy becomes something you can test during development, the same way you test correctness or performance, rather than something you discover on a cloud bill.
|
|
29
|
+
|
|
30
|
+
## Quickstart
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pipx install "green-bench[plots]" # or: pip install "green-bench[plots]"; drop [plots] if you don't need the charts
|
|
34
|
+
green-bench --version
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
You also need [EnergiBridge](https://github.com/tdurieux/EnergiBridge) installed. Then try the built-in example (two versions of an N-Queens solver; no project of your own needed):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
green-bench demo
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The demo copies the two example programs into `./green-bench-demo/` and **prints the exact `green-bench` command it runs**, so you can reuse it on your own project. With two directories that hold the two versions of your project, that looks like:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
green-bench \
|
|
47
|
+
--name my-experiment \
|
|
48
|
+
--base ./project-v1 \
|
|
49
|
+
--compare ./project-v2 \
|
|
50
|
+
--setup 'true' \
|
|
51
|
+
--cmd 'python workload.py' \
|
|
52
|
+
-n 30
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Results are written to `green-bench-results/my-experiment/`:
|
|
56
|
+
|
|
57
|
+
- `data.csv` (one row per run)
|
|
58
|
+
- `results.csv` (the statistics)
|
|
59
|
+
- two plots
|
|
60
|
+
- `output.log`.
|
|
61
|
+
|
|
62
|
+
## Requirements
|
|
63
|
+
|
|
64
|
+
- Python 3.10+
|
|
65
|
+
- **[EnergiBridge](https://github.com/tdurieux/EnergiBridge)** installed so that `energibridge --version` works in your terminal. It reads hardware energy counters, which usually requires elevated privileges (e.g. running the terminal with `sudo` on macOS/Linux). Follow its README for current installation instructions and supported hardware.
|
|
66
|
+
- Two directories containing the versions to compare (for example two `git clone`/`git worktree` checkouts of different branches or commits).
|
|
67
|
+
- A workload that is _computationally significant_: it should run for several seconds, not milliseconds, and do the same work every time.
|
|
68
|
+
|
|
69
|
+
## Before you measure
|
|
70
|
+
|
|
71
|
+
GreenBench measures system-wide power, so anything else your machine is doing ends up in the numbers. To reduce noise:
|
|
72
|
+
|
|
73
|
+
- Close other applications and background processes
|
|
74
|
+
- Plug into power and disable sleep
|
|
75
|
+
- Turn off Wi-Fi/Bluetooth if the workload does not need them
|
|
76
|
+
- Run from a plain terminal, not an IDE
|
|
77
|
+
- Keep the room temperature and the laptop's position consistent between sessions
|
|
78
|
+
- If you can, run your services natively rather than inside Docker Desktop, whose VM adds background CPU load
|
|
79
|
+
- Run the workload as a plain script rather than through a test runner, which adds its own overhead
|
|
80
|
+
|
|
81
|
+
## Options
|
|
82
|
+
|
|
83
|
+
| Flag | Default | Meaning |
|
|
84
|
+
| -------------------- | --------------------- | ----------------------------------------------------------------------------------- |
|
|
85
|
+
| `--name` | required | Name of the experiment (becomes the results folder; letters, digits, `.`, `_`, `-`) |
|
|
86
|
+
| `--base`, `-b` | required | Directory with the **baseline** version |
|
|
87
|
+
| `--compare`, `-c` | required | Directory with the **treatment** version |
|
|
88
|
+
| `--setup` | required | Shell command run before every measurement, _not_ measured (use `true` for none) |
|
|
89
|
+
| `--cmd` | required | Shell command to measure |
|
|
90
|
+
| `--iterations`, `-n` | `30` | Runs per version (30+ recommended; below 10 results are unreliable) |
|
|
91
|
+
| `--intensity` | `475` | Grid carbon intensity in gCO2e/kWh |
|
|
92
|
+
| `--output`, `-o` | `green-bench-results` | Where results are saved |
|
|
93
|
+
| `--seed` | random | Seed for the run order (printed at the start so you can reproduce it) |
|
|
94
|
+
| `--cooldown` | `10` | Seconds between setup and measurement |
|
|
95
|
+
| `--interval` | `500` | EnergiBridge sampling interval (ms) |
|
|
96
|
+
| `--timeout` | none | Abort any single command after this many seconds |
|
|
97
|
+
| `--keep-raw` | off | Keep every run's raw EnergiBridge CSV in `<results>/raw/` |
|
|
98
|
+
| `--resume` | off | Continue an interrupted experiment of the same name |
|
|
99
|
+
| `--overwrite` | off | Replace an existing results folder without asking (otherwise you are prompted) |
|
|
100
|
+
| `--no-plots` | off | Skip chart generation |
|
|
101
|
+
|
|
102
|
+
## How it works (short version)
|
|
103
|
+
|
|
104
|
+
1. **Pre-flight**: checks both directories and that EnergiBridge works.
|
|
105
|
+
2. **Warm-up**: runs each version once (discarded) so caches and JITs are warm.
|
|
106
|
+
3. **Experiment**: for each of _n_ blocks, runs one baseline and one treatment in **random order within the block** (_block-randomized interleaving_), so slow drifts such as heat build-up cannot favor one version. Before each run: setup command, then a cooldown.
|
|
107
|
+
4. **Analysis**: integrates power over time to get Joules, then compares the two groups with a Mann-Whitney U test, reports medians, effect size and a bootstrap confidence interval, and converts the difference to gCO2e.
|
|
108
|
+
|
|
109
|
+
A technical reference for architecture diagrams, statistics, and limitations is coming soon.
|
|
110
|
+
|
|
111
|
+
## What it found in practice (a case study)
|
|
112
|
+
|
|
113
|
+
GreenBench was validated on a real-world web application under active development: a Node.js / PostgreSQL / Redis platform for refurbished spare parts. The test workload was a bulk import that parsed, matched and imported 1,070 inventory rows. Each comparison used 30 runs per version on an Apple M1 MacBook Air.
|
|
114
|
+
|
|
115
|
+
| Comparison | Energy change | Significant? |
|
|
116
|
+
| ------------------------------------------------------------------------- | ------------- | ------------------- |
|
|
117
|
+
| Control: identical code vs. itself | −2.17% | No (p = 0.126) |
|
|
118
|
+
| Code level: refactoring long, complex methods | −3.22% | No (p = 0.105) |
|
|
119
|
+
| Logic level: Protobuf instead of JSON between services | +1.07% | No (p = 0.363) |
|
|
120
|
+
| Logic level: bulk database I/O instead of row-by-row queries | **−63.24%** | **Yes** (p < 0.001) |
|
|
121
|
+
| Architecture: microservices merged into a single-process modular monolith | **+22.46%** | **Yes** (p < 0.001) |
|
|
122
|
+
|
|
123
|
+
The control run shows that GreenBench does not report false differences when nothing has changed. The treatments show where energy is actually decided: higher-level design decisions such as data access patterns and architecture, not code cleanliness.
|
|
124
|
+
|
|
125
|
+
These results belong to one application and one workload, and yours will differ. That is the point of GreenBench: to empower developers like you to measure your own system for real impact!
|
|
126
|
+
|
|
127
|
+
## Development
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install -e ".[dev]"
|
|
131
|
+
pytest -m "not integration" # no energy hardware needed
|
|
132
|
+
ruff check src tests
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
See [CONTRIBUTING.md](https://github.com/jessicadraper/green-bench/blob/main/CONTRIBUTING.md) and the [CHANGELOG.md](https://github.com/jessicadraper/green-bench/blob/main/CHANGELOG.md).
|
|
136
|
+
|
|
137
|
+
## Background and citation
|
|
138
|
+
|
|
139
|
+
GreenBench was created as part of the MSc thesis _"Evaluating the Environmental Impact of Software Design: An Empirical Analysis using Automated Software Emissions Benchmarking"_ by Jessica Draper (Software Design and Engineering, Hochschule Campus Wien, Vienna, 2026). If you use GreenBench in research, please cite it (see [CITATION.cff](https://github.com/jessicadraper/green-bench/blob/main/CITATION.cff)).
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT, see [LICENSE](https://github.com/jessicadraper/green-bench/blob/main/LICENSE).
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "green-bench"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A CLI tool for automated, localized software energy experiments."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Jessica Draper", email = "jessicafaye.draper@gmail.com" }
|
|
15
|
+
]
|
|
16
|
+
keywords = ["green software", "energy", "benchmark", "carbon", "sustainability", "energibridge"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Environment :: Console",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Intended Audience :: Science/Research",
|
|
22
|
+
"Operating System :: MacOS",
|
|
23
|
+
"Operating System :: POSIX :: Linux",
|
|
24
|
+
"Operating System :: Microsoft :: Windows",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Topic :: Software Development :: Testing",
|
|
31
|
+
"Topic :: System :: Benchmark",
|
|
32
|
+
]
|
|
33
|
+
dependencies = [
|
|
34
|
+
"typer>=0.12.0", # CLI framework
|
|
35
|
+
"rich>=13.0.0", # terminal output
|
|
36
|
+
"pandas>=2.2.0", # results data structuring
|
|
37
|
+
"numpy>=2.0.0", # numerical integration (np.trapezoid)
|
|
38
|
+
"scipy>=1.12.0", # Mann-Whitney U test
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
plots = [
|
|
43
|
+
"matplotlib>=3.8.0",
|
|
44
|
+
"seaborn>=0.13.0",
|
|
45
|
+
]
|
|
46
|
+
dev = [
|
|
47
|
+
"pytest>=8.0.0",
|
|
48
|
+
"psutil>=6.0.0", # only used by the observer-effect integration test
|
|
49
|
+
"ruff>=0.5.0",
|
|
50
|
+
"matplotlib>=3.8.0",
|
|
51
|
+
"seaborn>=0.13.0",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[project.urls]
|
|
55
|
+
Homepage = "https://github.com/jessicadraper/green-bench"
|
|
56
|
+
Repository = "https://github.com/jessicadraper/green-bench"
|
|
57
|
+
Issues = "https://github.com/jessicadraper/green-bench/issues"
|
|
58
|
+
|
|
59
|
+
[project.scripts]
|
|
60
|
+
green-bench = "green_bench.__main__:app"
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.package-data]
|
|
63
|
+
green_bench = ["demo_data/**/*.py"]
|
|
64
|
+
|
|
65
|
+
[tool.setuptools.dynamic]
|
|
66
|
+
version = { attr = "green_bench.__version__" }
|
|
67
|
+
|
|
68
|
+
[tool.pytest.ini_options]
|
|
69
|
+
testpaths = ["tests"]
|
|
70
|
+
markers = ["integration: needs the real EnergiBridge binary and hardware access"]
|
|
71
|
+
filterwarnings = [
|
|
72
|
+
# seaborn 0.13.2 still passes `vert=` to matplotlib >= 3.10 internally; not fixable from our code.
|
|
73
|
+
# Remove once a seaborn release no longer triggers it.
|
|
74
|
+
"ignore:.*bool will be deprecated in a future version:PendingDeprecationWarning",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[tool.ruff]
|
|
78
|
+
line-length = 120
|
|
79
|
+
target-version = "py310"
|
|
80
|
+
|
|
81
|
+
[tool.ruff.lint]
|
|
82
|
+
select = ["E", "F", "I"]
|
|
83
|
+
ignore = ["E501"] # long CLI help strings
|