From cddb4961801324e3e56a400bf039e2c4a877a603 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 26 May 2026 04:35:12 -0400 Subject: [PATCH] Add file benchmark --- .github/workflows/ci.yml | 11 ++++- .../sbt/internal/util/FileHashBenchmark.scala | 49 +++++++++++++++++++ .../src/main/scala/sbt/util/Digest.scala | 3 ++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 internal/hash-benchmark/src/main/scala/sbt/internal/util/FileHashBenchmark.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b281bfd9..1bc8a9689 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,10 @@ jobs: java: 17 distribution: zulu jobtype: 12 + - os: ubuntu-latest + java: 17 + distribution: temurin + jobtype: 13 runs-on: ${{ matrix.os }} timeout-minutes: 25 env: @@ -202,4 +206,9 @@ jobs: if: ${{ matrix.jobtype == 12 }} shell: bash run: | - ./sbt -v "scripted cache/*" \ No newline at end of file + ./sbt -v "scripted cache/*" + - name: Hash Benchmark + if: ${{ matrix.jobtype == 13 }} + shell: bash + run: | + ./sbt -v "hashBenchmark/Jmh/run -i 5 -wi 3 -f1 -t1" diff --git a/internal/hash-benchmark/src/main/scala/sbt/internal/util/FileHashBenchmark.scala b/internal/hash-benchmark/src/main/scala/sbt/internal/util/FileHashBenchmark.scala new file mode 100644 index 000000000..0c39c43c5 --- /dev/null +++ b/internal/hash-benchmark/src/main/scala/sbt/internal/util/FileHashBenchmark.scala @@ -0,0 +1,49 @@ +package sbt.internal.util + +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.annotations.* +import sbt.util.Digest + +import java.nio.file.{ Path as NioPath } +import sbt.io.IO +import sbt.io.syntax.* + +@State(Scope.Benchmark) +abstract class AbstractFileHashBenchmark: + val tempDir = IO.createTemporaryDirectory + val temp = tempDir / "test.txt" + val buf: Array[Byte] = Array.fill[Byte](1024)(0.toByte) + for i <- 0 until 1024 do IO.append(temp, buf) + + def hash(path: NioPath): String + + @Benchmark + @BenchmarkMode(Array(Mode.AverageTime)) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + def hashFile: Unit = + hash(temp.toPath()) +end AbstractFileHashBenchmark + +class XXHash64FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.xx64Hash(path).toString + +class WyHash64FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.wy64Hash(path).toString + +class ImoXXHash64FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.imoxx64Hash(path).toString + +class ImoWyHash64FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.imowy64Hash(path).toString + +class Sha1FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.sha1Hash(path).toString + +class Sha256FileHashBenchmark extends AbstractFileHashBenchmark: + override def hash(path: NioPath): String = + Digest.sha256Hash(path).toString diff --git a/util-cache/src/main/scala/sbt/util/Digest.scala b/util-cache/src/main/scala/sbt/util/Digest.scala index 05742dbb3..ac662a3f1 100644 --- a/util-cache/src/main/scala/sbt/util/Digest.scala +++ b/util-cache/src/main/scala/sbt/util/Digest.scala @@ -75,6 +75,9 @@ object Digest: lazy val zero: Digest = dummy(0L) + private[sbt] def sha1Hash(path: Path): Digest = + apply(Sha1, path) + def sha256Hash(path: Path): Digest = apply(Sha256, path) def sha256Hash(bytes: Array[Byte]): Digest =