Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/ops/bin/benchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ fi

SCRIPT_PATH=$(dirname "$(realpath -s "$0")")
DOCS_OPS_PATH="$SCRIPT_PATH/.."
INC_PATH="$DOCS_OPS_PATH/../../"
BENCHMARKS_PATH="$INC_PATH/scijava-ops-benchmarks"
BASE_PATH="$DOCS_OPS_PATH/../../"
BENCHMARKS_PATH="$BASE_PATH/scijava-ops-benchmarks"
BENCH_OUT_FILE=scijava-ops-benchmarks_results.json
BENCH_OUT_PATH=$(realpath -s "$DOCS_OPS_PATH/$BENCH_OUT_FILE")

Expand All @@ -24,8 +24,8 @@ then
else
echo
echo '=== BUILDING THE CODE ==='
cd "$INC_PATH"
mvn -Denforcer.skip -Dinvoker.skip -Dmaven.test.skip -P benchmarks clean install -pl scijava-ops-benchmarks -am | grep '\(Building.*[0-9]\]\|ERROR\)'
cd "$BASE_PATH"
mvn -Denforcer.skip -Dinvoker.skip -Dmaven.test.skip -P benchmarks clean install -pl scijava-ops-benchmarks -am

echo
echo '=== COPYING DEPENDENCIES ==='
Expand Down
14 changes: 7 additions & 7 deletions docs/ops/doc/Benchmarks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Hardware and Software

This analysis was performed with the following hardware:

* 2021 Dell OptiPlex 5090 Small Form Factor
* Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz
* 64 GB 3200 MHz DDR4 RAM
* Mainboard: Gigabyte Technology Co., Ltd. X570 AORUS PRO WIFI
* CPU: AMD Ryzen 7 3700X × 16
* Memory: 32 GB 3200 MHz DDR4 RAM

The following software components were used:

* Ubuntu 20.04.6 LTS
* Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 20.0.1+9.1 (build 20.0.1+9-jvmci-23.0-b12, mixed mode, sharing)
* SciJava core commit `0b8012b2 <https://github.com/scijava/scijava/commit/0b8012b2b00ba84b0583ef7260fab1be8f251041>`_
* Ubuntu 24.04 LTS
* OpenJDK 64-Bit Server VM Zulu11.72+19-CA (build 11.0.23+9-LTS, mixed mode)
* SciJava core commit `018d03ed <https://github.com/scijava/scijava/commit/018d03edd2c4fd20747b472d87f65a8a7033bfe1>`_
* ImageJ Ops version ``2.0.0``

All benchmarks are executed using the `Java Microbenchmark Harness <https://github.com/openjdk/jmh>`_, using the following parameters:
Expand Down Expand Up @@ -119,7 +119,7 @@ Reproducing these Results
1. Create a local copy of the SciJava core from the `GitHub repository <https://github.com/scijava/scijava>`_
2. Ensure you have package manager `Mamba <https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html#fresh-install-recommended>`_ installed.
3. Run the script `docs/ops/bin/benchmark.sh`, which will:
* Create the mamba Environment
* Create the mamba environment
* Build the benchmarking code
* Execute all JMH benchmarks
* Build `plotly <https://plotly.com/>`_ figures for each benchmark
Expand Down
2 changes: 1 addition & 1 deletion docs/ops/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies:
- myst-nb
- openjdk=11
- plotly
- sphinx
- sphinx=7.2
- sphinx-copybutton
- sphinx_rtd_theme

Expand Down
113 changes: 77 additions & 36 deletions docs/ops/graph_results.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import json
import math
import statistics

import plotly.graph_objects as go
import plotly.io as io
from plotly.subplots import make_subplots

# This script parses JMH benchmarking results into charts developed using plot.ly (https://plotly.com/)
# It expects JMH benchmark results be dumped to a file "scijava-ops-benchmark_results.json", within its directory.
Expand All @@ -17,54 +19,54 @@
"name": "BenchmarkMatching",
"title": "Basic Op Matching Performance",
"bars": {
"noOps": "Static Method",
"noOpsAdapted": f"Static Method {A}",
"sjOpsAdapted": f"SciJava Ops {A}",
"sjOps": "SciJava Ops",
"sjOpsAdapted": f"SciJava Ops {A}"
"noOpsAdapted": f"Static Method {A}",
"noOps": "Static Method",
}
},
{
"name": "BenchmarkCaching",
"title": "Caching Effects on Op Matching Performance",
"bars": {
"noOps": "Static Method",
"sjOpsWithCache": "SciJava Ops (cached)",
"sjOps": "SciJava Ops",
"sjOpsWithCache": "SciJava Ops (cached)"
"noOps": "Static Method",
}
},
{
"name": "BenchmarkConversion",
"title": "Parameter Conversion Performance",
"bars": {
"noOpsConverted": f"Static Method {C}",
"noOpsAdaptedAndConverted": f"Static Method {AC}",
"sjOpsConvertedAndAdapted": f"SciJava Ops {AC}",
"sjOpsConverted": f"SciJava Ops {C}",
"sjOpsConvertedAndAdapted": f"SciJava Ops {AC}"
"noOpsAdaptedAndConverted": f"Static Method {AC}",
"noOpsConverted": f"Static Method {C}",
}
},
{
"name": "BenchmarkFrameworks",
"title": "Algorithm Execution Performance by Framework",
"bars": {
"noOps": "Static Method",
"ijOps": "ImageJ Ops",
"sjOps": "SciJava Ops",
"ijOps": "ImageJ Ops"
"noOps": "Static Method",
}
},
{
"name": "BenchmarkCombined",
"title": "Combined Performance Metrics",
"bars": {
"noOps": "Static Method",
"noOpsAdapted": f"Static Method {A}",
"noOpsConverted": f"Static Method {C}",
"noOpsAdaptedAndConverted": f"Static Method {AC}",
"sjOpsWithCache": "SciJava Ops (cached)",
"sjOps": "SciJava Ops",
"sjOpsAdapted": f"SciJava Ops {A}",
"sjOpsConverted": f"SciJava Ops {C}",
"sjOpsConvertedAndAdapted": f"SciJava Ops {AC}",
"ijOps": "ImageJ Ops",
"sjOpsConvertedAndAdapted": f"SciJava Ops {AC}",
"sjOpsConverted": f"SciJava Ops {C}",
"sjOpsAdapted": f"SciJava Ops {A}",
"sjOps": "SciJava Ops",
"sjOpsWithCache": "SciJava Ops (cached)",
"noOpsAdaptedAndConverted": f"Static Method {AC}",
"noOpsConverted": f"Static Method {C}",
"noOpsAdapted": f"Static Method {A}",
"noOps": "Static Method",
}
}
]
Expand All @@ -87,32 +89,71 @@
name = figure["name"]
print(f"Generating figure for {name}", end="")

x = []
y = []
error_y = []
error_y_minus = []
labels = []
values = []
errors = []

# Add each benchmark in the class
for test, label in figure["bars"].items():
print(f".", end="")
print(".", end="")
result = results[test]
x.append(label)
y.append(result["score"])
error_y.append(result["minmax"][1] - result["score"])
error_y_minus.append(result["score"] - result["minmax"][0])

# Create a bar chart
fig = go.Figure()
fig.add_bar(
x=x,
y=y,
error_y=dict(type='data', array=error_y, arrayminus=error_y_minus),
labels.append(label)
score = result["score"]
values.append(score)
error = [result["minmax"][1] - score, score - result["minmax"][0]]
errors.append(error)

# Create a subplot with shared y-axis
fig = make_subplots(rows=1, cols=2, shared_yaxes=True, horizontal_spacing=0.02)

# Add log scale bars (left side)
fig.add_trace(
go.Bar(
y=labels,
x=values,
orientation='h',
error_x=dict(type='data', symmetric=False, array=[e[0] for e in errors], arrayminus=[e[1] for e in errors]),
name="Log Scale",
marker_color='blue'
),
row=1, col=1
)

# Add linear scale bars (right side)
fig.add_trace(
go.Bar(
y=labels,
x=values,
orientation='h',
error_x=dict(type='data', symmetric=False, array=[e[0] for e in errors], arrayminus=[e[1] for e in errors]),
name="Linear Scale",
marker_color='red'
),
row=1, col=2
)

# Update layout
fig.update_layout(
title_text=figure["title"] + f"<br><sup style=\"color: gray\">{A}=Adaptation, {C}=Conversion, {AC}=Adaptation & Conversion</sup>",
yaxis_title="<b>Performance (&mu;s/execution)</b>"
barmode='relative',
yaxis=dict(title=""),
#xaxis=dict(title="Log Scale (μs/execution)", type="log"),
xaxis=dict(
title="Log Scale (μs/execution)",
type="log",
range=[min(values), max(values)],
),
xaxis2=dict(title="Linear Scale (μs/execution)"),
height=max(500, 50 * len(labels)), # Adjust height based on number of bars
showlegend=False
)

# Add a vertical line at x=0
fig.add_vline(x=0, line_width=2, line_color="black")

# Reverse the log scale axis
fig.update_xaxes(autorange="reversed", row=1, col=1)

# Convert to JSON and dump
with open(f"images/{name}.json", "w") as f:
f.write(io.to_json(fig))
Expand Down
2 changes: 1 addition & 1 deletion docs/ops/images/BenchmarkCaching.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ops/images/BenchmarkCombined.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ops/images/BenchmarkConversion.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ops/images/BenchmarkFrameworks.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ops/images/BenchmarkMatching.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,13 @@
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
</properties>

<profiles>
<profile>
<id>benchmarks</id>
<modules>
<module>scijava-ops-benchmarks</module>
</modules>
</profile>
</profiles>
</project>
2 changes: 2 additions & 0 deletions scijava-ops-benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -338,5 +338,7 @@
</pluginManagement>
</build>
</profile>
<!-- HACK: Squelch profile activation warning. -->
<profile><id>benchmarks</id></profile>
</profiles>
</project>