Skip to content
Open
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
51 changes: 51 additions & 0 deletions .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CodSpeed Benchmarks

on:
push:
branches: [main, master]
pull_request:
# `workflow_dispatch` allows CodSpeed to trigger backtest
# performance analysis in order to generate initial data.
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read # required for actions/checkout
id-token: write # required for OIDC authentication with CodSpeed

jobs:
benchmarks:
name: Run benchmarks
# CodSpeed macro runners give much more stable walltime measurements.
# Switch to `runs-on: codspeed-macro` once they are enabled for this
# organization: https://codspeed.io/docs/features/macro-runners
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Only fetch the CodSpeed JMH fork and its native hooks, not the
# example submodules bundled with codspeed-jvm.
- name: Fetch the CodSpeed JMH fork
run: |
git submodule update --init third-party/codspeed-jvm
git -C third-party/codspeed-jvm submodule update --init \
jmh-fork/jmh-core/native-instrument-hooks/instrument-hooks

- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"

- name: Build the benchmark jar
working-directory: bench
run: ./gradlew --no-daemon jmhJar

- name: Run the benchmarks
uses: CodSpeedHQ/action@v5
with:
mode: walltime
run: java -jar bench/build/libs/clojure-algorithms-bench-jmh.jar -gc true
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
*.class
/out/
node_modules/
.DS_Store
.DS_Store
.gradle/
/bench/build/
!/bench/gradle/wrapper/gradle-wrapper.jar
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "third-party/codspeed-jvm"]
path = third-party/codspeed-jvm
url = https://github.com/CodSpeedHQ/codspeed-jvm.git
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Clojure Algorithms

[![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://app.codspeed.io/hhh-pa/clojure-algorithms?utm_source=badge)

A Clojure port of [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python) —
classic algorithms and data structures implemented in idiomatic Clojure.

Expand Down Expand Up @@ -52,6 +54,29 @@ clojure -M:cljfmt
clojure -T:build jar
```

## Benchmarks

Performance is tracked continuously with [CodSpeed](https://codspeed.io)
using [JMH](https://github.com/openjdk/jmh) through the CodSpeed JMH fork
(`third-party/codspeed-jvm`, a git submodule). The benchmarks live in
`bench/`: Java JMH classes in `bench/src/jmh/java` call the Clojure
functions directly, with deterministic inputs built in
`bench/src/jmh/clojure/clojure_algorithms/bench/fixtures.clj`.

```bash
# Fetch the CodSpeed JMH fork
git submodule update --init third-party/codspeed-jvm
git -C third-party/codspeed-jvm submodule update --init \
jmh-fork/jmh-core/native-instrument-hooks/instrument-hooks

# Run all benchmarks (or a subset with -Pbench=<regex>, e.g. -Pbench=Sorts)
(cd bench && ./gradlew jmh)

# Run them with the CodSpeed runner
(cd bench && ./gradlew jmhJar)
codspeed run --mode walltime -- java -jar bench/build/libs/clojure-algorithms-bench-jmh.jar
```

## Structure

```
Expand Down
44 changes: 44 additions & 0 deletions bench/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
java
id("me.champeau.jmh") version "0.7.3"
}

repositories {
mavenCentral()
}

java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

sourceSets {
named("jmh") {
// Clojure sources are loaded (and compiled) at runtime from the
// classpath, so the library and the benchmark fixtures are shipped as
// resources of the benchmark jar.
resources {
srcDir("../src")
srcDir("../resources")
srcDir("src/jmh/clojure")
}
}
}

dependencies {
// Keep in sync with deps.edn
jmh("org.clojure:clojure:1.12.0")
}

jmh {
// Resolved to the CodSpeed JMH fork through the composite build in
// settings.gradle.kts.
jmhVersion.set("0.2.1")

// Warmup/measurement/fork settings are declared with annotations on the
// benchmark classes so they also apply when running the jar directly.
forceGC.set(true)

// Optional benchmark filter, e.g. `./gradlew jmh -Pbench=Sorts`
project.findProperty("bench")?.let { includes.set(listOf(it.toString())) }
}
Binary file added bench/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions bench/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading
Loading