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
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:

- name: Run benchmarks
run: |
./build/sbt -Dspark.version=4.0.0 "benchmarks/Jmh/run -rf json"
python ./dev/run_doc_benchmarks.py --spark-version 4.0.0

- name: Build with Laika
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import java.util.concurrent.TimeUnit
"--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED"))
class ConnectedComponentsBenchmark extends LDBCBenchmarkBase {
@Param(Array("graphframes", "graphx"))
@Param(Array("graphframes", "graphx", "randomized_contraction"))
var algorithm: String = _

@Param(Array("1000000", "-1"))
Expand Down
70 changes: 70 additions & 0 deletions dev/run_doc_benchmarks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3

import argparse
import json
import subprocess
from pathlib import Path


def run_sbt(sbt_cmd: str, spark_version: str, jmh_args: str, repo_root: Path) -> None:
subprocess.run(
[sbt_cmd, f"-Dspark.version={spark_version}", jmh_args],
check=True,
cwd=repo_root,
)


def load_json_array(path: Path) -> list[dict]:
with path.open("r", encoding="utf-8") as file:
data = json.load(file)
if not isinstance(data, list):
raise ValueError(f"Expected a JSON array in {path}")
return data


def main() -> None:
repo_root = Path(__file__).resolve().parent.parent
parser = argparse.ArgumentParser(description="Run benchmarks needed for docs generation")
parser.add_argument("--spark-version", default="4.0.0")
parser.add_argument("--sbt", default=str((repo_root / "build" / "sbt").resolve()))
args = parser.parse_args()

results_dir = (repo_root / "benchmarks" / "target" / "doc-jmh").resolve()
results_dir.mkdir(parents=True, exist_ok=True)

benchmark_commands = [
(
results_dir / "shortest-paths.json",
"benchmarks/Jmh/run -rf json -p graphName=wiki-Talk -p useLocalCheckpoints=true "
"-p algorithm=graphframes,graphx "
"org.graphframes.benchmarks.ShortestPathsBenchmark",
),
(
results_dir / "connected-components.json",
"benchmarks/Jmh/run -rf json -p graphName=wiki-Talk -p useLocalCheckpoints=true "
"-p algorithm=graphframes,graphx -p broadcastThreshold=-1 "
"org.graphframes.benchmarks.ConnectedComponentsBenchmark",
),
(
results_dir / "label-propagation.json",
"benchmarks/Jmh/run -rf json -p graphName=wiki-Talk -p useLocalCheckpoints=true "
"-p algorithm=graphframes,graphx "
"org.graphframes.benchmarks.LabelPropagationBenchmark",
),
]

all_results: list[dict] = []
for output_file, cmd in benchmark_commands:
run_sbt(args.sbt, args.spark_version, f"{cmd} -rff {output_file}", repo_root)
all_results.extend(load_json_array(output_file))

target_file = (repo_root / "benchmarks" / "jmh-result.json").resolve()
with target_file.open("w", encoding="utf-8") as file:
json.dump(all_results, file, indent=2)
file.write("\n")

print(f"Saved {len(all_results)} benchmark entries to {target_file}")


if __name__ == "__main__":
main()
16 changes: 8 additions & 8 deletions docs/src/01-about/03-benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ algorithms is measured and the time of reading of the CSV, serialization and per
- **Size Category:** _XS_
- **Source files format:** `CSV`-like

| Algorithm | Measurements | Time (s) |
| -------------------------------- | ---------------------------------------------- | ---------------------------------------- |
| Shortest Paths Graphframes | ${benchmarks.benchmarkSP.measurements} | ${benchmarks.benchmarkSP.metric} |
| Shortest Paths GraphX | ${benchmarks.benchmarkSPGraphX.measurements} | ${benchmarks.benchmarkSPGraphX.metric} |
| Connected Components Graphframes | ${benchmarks.benchmarkCC.measurements} | ${benchmarks.benchmarkCC.metric} |
| Connected Components GraphX | ${benchmarks.benchmarkCCGraphX.measurements} | ${benchmarks.benchmarkCCGraphX.metric} |
| Label Propagation GraphFrames | ${benchmarks.benchmarkCDLP.measurements} | ${benchmarks.benchmarkCDLP.metric} |
| Label Propagation GraphX | ${benchmarks.benchmarkCDLPGraphX.measurements} | ${benchmarks.benchmarkCDLPGraphX.metric} |
Comment thread
SemyonSinchenko marked this conversation as resolved.
| Algorithm | Measurements | Time (s) |
| -------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------- |
| Shortest Paths Graphframes | ${benchmarks.benchmarkShortestPaths.graphframes.measurements} | ${benchmarks.benchmarkShortestPaths.graphframes.metric} |
| Shortest Paths GraphX | ${benchmarks.benchmarkShortestPaths.graphx.measurements} | ${benchmarks.benchmarkShortestPaths.graphx.metric} |
| Connected Components Graphframes | ${benchmarks.benchmarkConnectedComponents.graphframes.measurements} | ${benchmarks.benchmarkConnectedComponents.graphframes.metric} |
| Connected Components GraphX | ${benchmarks.benchmarkConnectedComponents.graphx.measurements} | ${benchmarks.benchmarkConnectedComponents.graphx.metric} |
| Label Propagation GraphFrames | ${benchmarks.benchmarkLabelPropagation.graphframes.measurements} | ${benchmarks.benchmarkLabelPropagation.graphframes.metric} |
| Label Propagation GraphX | ${benchmarks.benchmarkLabelPropagation.graphx.measurements} | ${benchmarks.benchmarkLabelPropagation.graphx.metric} |
55 changes: 38 additions & 17 deletions project/LaikaCustoms.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ object LaikaCustoms {
{
val name =
bench.hcursor.downField("benchmark").as[String].getOrElse("").split("\\.").last
val algorithm =
bench.hcursor
.downField("params")
.downField("algorithm")
.as[String]
.getOrElse("")
val keyName = if (algorithm.nonEmpty) s"$name.$algorithm" else name
val measurements =
bench.hcursor.downField("measurementIterations").as[Int].getOrElse(-1)
val metric = bench.hcursor
Expand All @@ -169,25 +176,39 @@ object LaikaCustoms {
.as[Array[Double]]
.getOrElse(Array.empty)

quantiles.foldLeft(
config
.withConfigValue(s"benchmarks.$name.metric", f"$metric%.4f")
.withConfigValue(s"benchmarks.$name.measurements", measurements)
.withConfigValue(
s"benchmarks.$name.ciLeft",
f"${Try(confidence(0)).getOrElse(0.0)}%.4f")
.withConfigValue(
s"benchmarks.$name.ciRight",
f"${Try(confidence(1)).getOrElse(0.0)}%.4f")
.withConfigValue(s"benchmarks.$name.stdErr", f"$stdErr%.4f")) {
(conf, quantile) =>
{
conf
def addMetrics(conf: LaikaConfig, key: String): LaikaConfig = {
quantiles.foldLeft(
conf
.withConfigValue(s"benchmarks.$key.metric", f"$metric%.4f")
.withConfigValue(s"benchmarks.$key.measurements", measurements)
.withConfigValue(
s"benchmarks.$key.ciLeft",
f"${Try(confidence(0)).getOrElse(0.0)}%.4f")
.withConfigValue(
s"benchmarks.$key.ciRight",
f"${Try(confidence(1)).getOrElse(0.0)}%.4f")
.withConfigValue(s"benchmarks.$key.stdErr", f"$stdErr%.4f")) {
(acc, quantile) =>
acc
.withConfigValue(
s"benchmarks.$name.quantiles.${quantile._1}",
f"${quantile._2}.4f")
}
s"benchmarks.$key.quantiles.${quantile._1}",
f"${quantile._2}%.4f")
}
}

val withKeyName = addMetrics(config, keyName)

val maybeLegacyAlias = (name, algorithm) match {
case ("benchmarkShortestPaths", "graphframes") => Some("benchmarkSP")
case ("benchmarkShortestPaths", "graphx") => Some("benchmarkSPGraphX")
case ("benchmarkConnectedComponents", "graphframes") => Some("benchmarkCC")
case ("benchmarkConnectedComponents", "graphx") => Some("benchmarkCCGraphX")
case ("benchmarkLabelPropagation", "graphframes") => Some("benchmarkCDLP")
case ("benchmarkLabelPropagation", "graphx") => Some("benchmarkCDLPGraphX")
case _ => None
}

maybeLegacyAlias.map(alias => addMetrics(withKeyName, alias)).getOrElse(withKeyName)
}
})
}
Expand Down
Loading