From 56ae0b6e53884bd2b38580e35baf076da0209143 Mon Sep 17 00:00:00 2001 From: rafambn Date: Wed, 9 Sep 2026 01:48:20 -0300 Subject: [PATCH 1/2] Refine level 9 matches with dynamic Huffman prices --- .../rafambn/kflate/algorithm/DeflateCost.kt | 329 ++++++++++++++- .../com/rafambn/kflate/huffman/HuffmanCode.kt | 2 +- .../jvmTest/kotlin/AlgorithmCoverageTest.kt | 20 + performance/2026-09-09-dynamic/RESULTS.md | 58 +++ .../2026-09-09-dynamic/RatioSweep.java | 39 ++ performance/2026-09-09-dynamic/after-jmh.json | 380 ++++++++++++++++++ .../2026-09-09-dynamic/after-sizes.jsonl | 7 + .../2026-09-09-dynamic/before-jmh.json | 380 ++++++++++++++++++ .../2026-09-09-dynamic/before-sizes.jsonl | 70 ++++ .../2026-09-09-dynamic/native_bench.py | 38 ++ 10 files changed, 1312 insertions(+), 11 deletions(-) create mode 100644 performance/2026-09-09-dynamic/RESULTS.md create mode 100644 performance/2026-09-09-dynamic/RatioSweep.java create mode 100644 performance/2026-09-09-dynamic/after-jmh.json create mode 100644 performance/2026-09-09-dynamic/after-sizes.jsonl create mode 100644 performance/2026-09-09-dynamic/before-jmh.json create mode 100644 performance/2026-09-09-dynamic/before-sizes.jsonl create mode 100644 performance/2026-09-09-dynamic/native_bench.py diff --git a/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt b/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt index 5a59a15..25f12f7 100644 --- a/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt +++ b/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt @@ -6,6 +6,10 @@ import com.rafambn.kflate.huffman.FIXED_DISTANCE_TREE import com.rafambn.kflate.huffman.FIXED_LENGTH_EXTRA_BITS import com.rafambn.kflate.huffman.FIXED_LENGTH_REVERSE_LOOKUP import com.rafambn.kflate.huffman.FIXED_LENGTH_TREE +import com.rafambn.kflate.huffman.buildHuffmanTreeFromFrequencies +import com.rafambn.kflate.huffman.calculateCodeLength +import com.rafambn.kflate.huffman.generateLengthCodes +import com.rafambn.kflate.util.countCodeLengthCodes internal fun chooseCostAwarePath( data: ByteArray, @@ -15,13 +19,150 @@ internal fun chooseCostAwarePath( costs: IntArray, choices: IntArray, ) { - // Fixed-tree widths provide stable prices before token frequencies can define a dynamic tree. + chooseCostAwarePath( + data = data, + start = start, + end = end, + matches = matches, + costs = costs, + choices = choices, + literalCosts = FIXED_LITERAL_COSTS, + lengthCosts = FIXED_LENGTH_COSTS, + distanceCosts = FIXED_DISTANCE_COSTS, + ) + + val size = end - start + if (size < COST_AWARE_DYNAMIC_MIN_WINDOW) return + + val initialChoices = choices.copyOf() + val initialCosts = costs.copyOf() + val initialLiteralFrequencies = IntArray(288) + val initialDistanceFrequencies = IntArray(32) + collectPathFrequencies( + data = data, + start = start, + matches = matches, + choices = initialChoices, + size = size, + literalFrequencies = initialLiteralFrequencies, + distanceFrequencies = initialDistanceFrequencies, + ) + + val initialDynamicTrees = buildDynamicTrees( + initialLiteralFrequencies, + initialDistanceFrequencies, + ) + val initialDynamicCosts = dynamicTokenCosts( + initialDynamicTrees.first, + initialDynamicTrees.second, + ) + val initialFixedCost = calculatePathCost( + data = data, + start = start, + matches = matches, + choices = initialChoices, + size = size, + literalCosts = FIXED_LITERAL_COSTS, + lengthCosts = FIXED_LENGTH_COSTS, + distanceCosts = FIXED_DISTANCE_COSTS, + ) + val initialDynamicCost = calculateDynamicPathCost( + data = data, + start = start, + matches = matches, + choices = initialChoices, + size = size, + literalCosts = initialDynamicCosts.first, + lengthCosts = initialDynamicCosts.second, + distanceCosts = initialDynamicCosts.third, + literalTree = initialDynamicTrees.first, + distanceTree = initialDynamicTrees.second, + ) + + // Skip refinement when this window estimate favors fixed coding. + if (initialDynamicCost >= initialFixedCost) return + + chooseCostAwarePath( + data = data, + start = start, + end = end, + matches = matches, + costs = costs, + choices = choices, + literalCosts = initialDynamicCosts.first, + lengthCosts = initialDynamicCosts.second, + distanceCosts = initialDynamicCosts.third, + ) + + val refinedChoices = choices.copyOf() + val refinedLiteralFrequencies = IntArray(288) + val refinedDistanceFrequencies = IntArray(32) + collectPathFrequencies( + data = data, + start = start, + matches = matches, + choices = refinedChoices, + size = size, + literalFrequencies = refinedLiteralFrequencies, + distanceFrequencies = refinedDistanceFrequencies, + ) + + val refinedDynamicTrees = buildDynamicTrees( + refinedLiteralFrequencies, + refinedDistanceFrequencies, + ) + val refinedDynamicCosts = dynamicTokenCosts( + refinedDynamicTrees.first, + refinedDynamicTrees.second, + ) + val refinedFixedCost = calculatePathCost( + data = data, + start = start, + matches = matches, + choices = refinedChoices, + size = size, + literalCosts = FIXED_LITERAL_COSTS, + lengthCosts = FIXED_LENGTH_COSTS, + distanceCosts = FIXED_DISTANCE_COSTS, + ) + val refinedDynamicCost = calculateDynamicPathCost( + data = data, + start = start, + matches = matches, + choices = refinedChoices, + size = size, + literalCosts = refinedDynamicCosts.first, + lengthCosts = refinedDynamicCosts.second, + distanceCosts = refinedDynamicCosts.third, + literalTree = refinedDynamicTrees.first, + distanceTree = refinedDynamicTrees.second, + ) + + val initialEncodedCost = minOf(initialFixedCost, initialDynamicCost) + val refinedEncodedCost = minOf(refinedFixedCost, refinedDynamicCost) + if (refinedEncodedCost >= initialEncodedCost) { + initialChoices.copyInto(choices) + initialCosts.copyInto(costs) + } +} + +private fun chooseCostAwarePath( + data: ByteArray, + start: Int, + end: Int, + matches: IntArray, + costs: IntArray, + choices: IntArray, + literalCosts: IntArray, + lengthCosts: IntArray, + distanceCosts: IntArray, +) { val size = end - start costs[size] = 0 for (offset in size - 1 downTo 0) { val literal = data[start + offset].toInt() and 0xFF - var bestCost = fixedLiteralBitCost(literal) + costs[offset + 1] + var bestCost = literalCosts[literal] + costs[offset + 1] var bestLength = 1 val match = matches[offset] val distance = match and MATCH_DISTANCE_MASK @@ -30,7 +171,8 @@ internal fun chooseCostAwarePath( val searchedLength = minOf(containedLength, COST_AWARE_LENGTH_SEARCH) for (length in 3..searchedLength) { - val candidateCost = fixedMatchBitCost(length, distance) + costs[offset + length] + val candidateCost = matchBitCost(length, distance, lengthCosts, distanceCosts) + + costs[offset + length] if (candidateCost <= bestCost) { bestCost = candidateCost bestLength = length @@ -39,7 +181,7 @@ internal fun chooseCostAwarePath( if (maximumLength > searchedLength) { val nextCost = if (offset + maximumLength <= size) costs[offset + maximumLength] else 0 - val candidateCost = fixedMatchBitCost(maximumLength, distance) + nextCost + val candidateCost = matchBitCost(maximumLength, distance, lengthCosts, distanceCosts) + nextCost if (candidateCost <= bestCost) { bestCost = candidateCost bestLength = maximumLength @@ -51,20 +193,187 @@ internal fun chooseCostAwarePath( } } +private fun collectPathFrequencies( + data: ByteArray, + start: Int, + matches: IntArray, + choices: IntArray, + size: Int, + literalFrequencies: IntArray, + distanceFrequencies: IntArray, +) { + var offset = 0 + while (offset < size) { + val length = choices[offset] + if (length == 1) { + literalFrequencies[data[start + offset].toInt() and 0xFF]++ + } else { + val match = matches[offset] + val distance = match and MATCH_DISTANCE_MASK + val lengthSymbol = FIXED_LENGTH_REVERSE_LOOKUP[length] and 31 + val distanceSymbol = FIXED_DISTANCE_REVERSE_LOOKUP[distance] and 31 + literalFrequencies[257 + lengthSymbol]++ + distanceFrequencies[distanceSymbol]++ + } + offset += length + } + + literalFrequencies[256]++ + if (distanceFrequencies.all { it == 0 }) { + distanceFrequencies[0] = 1 + } +} + +private fun buildDynamicTrees( + literalFrequencies: IntArray, + distanceFrequencies: IntArray, +): Pair { + return Pair( + buildHuffmanTreeFromFrequencies(literalFrequencies, 15).tree, + buildHuffmanTreeFromFrequencies(distanceFrequencies, 15).tree, + ) +} + +private fun dynamicTokenCosts( + literalTree: ByteArray, + distanceTree: ByteArray, +): Triple { + val literalCosts = IntArray(288) + for (symbol in literalCosts.indices) { + val dynamicCost = literalTree.getOrNull(symbol)?.toInt()?.and(0xFF) ?: 0 + literalCosts[symbol] = if (dynamicCost > 0) dynamicCost else FIXED_LITERAL_COSTS[symbol] + } + + val lengthCosts = IntArray(31) + for (symbol in lengthCosts.indices) { + val dynamicCost = literalTree.getOrNull(257 + symbol)?.toInt()?.and(0xFF) ?: 0 + lengthCosts[symbol] = if (dynamicCost > 0) { + dynamicCost + (FIXED_LENGTH_EXTRA_BITS[symbol].toInt() and 0xFF) + } else { + FIXED_LENGTH_COSTS[symbol] + } + } + + val distanceCosts = IntArray(31) + for (symbol in distanceCosts.indices) { + val dynamicCost = distanceTree.getOrNull(symbol)?.toInt()?.and(0xFF) ?: 0 + distanceCosts[symbol] = if (dynamicCost > 0) { + dynamicCost + (FIXED_DISTANCE_EXTRA_BITS[symbol].toInt() and 0xFF) + } else { + FIXED_DISTANCE_COSTS[symbol] + } + } + + return Triple(literalCosts, lengthCosts, distanceCosts) +} + +private fun calculatePathCost( + data: ByteArray, + start: Int, + matches: IntArray, + choices: IntArray, + size: Int, + literalCosts: IntArray, + lengthCosts: IntArray, + distanceCosts: IntArray, +): Int { + var cost = literalCosts[256] + var offset = 0 + while (offset < size) { + val length = choices[offset] + if (length == 1) { + cost += literalCosts[data[start + offset].toInt() and 0xFF] + } else { + val match = matches[offset] + cost += matchBitCost( + length, + match and MATCH_DISTANCE_MASK, + lengthCosts, + distanceCosts, + ) + } + offset += length + } + return cost +} + +private fun calculateDynamicPathCost( + data: ByteArray, + start: Int, + matches: IntArray, + choices: IntArray, + size: Int, + literalCosts: IntArray, + lengthCosts: IntArray, + distanceCosts: IntArray, + literalTree: ByteArray, + distanceTree: ByteArray, +): Int { + val tokenCost = calculatePathCost( + data = data, + start = start, + matches = matches, + choices = choices, + size = size, + literalCosts = literalCosts, + lengthCosts = lengthCosts, + distanceCosts = distanceCosts, + ) + val (literalCodeLengths, _) = generateLengthCodes(literalTree) + val (distanceCodeLengths, _) = generateLengthCodes(distanceTree) + val codeLengthFrequencies = IntArray(19) + for (code in literalCodeLengths) { + codeLengthFrequencies[code.toInt() and 31]++ + } + for (code in distanceCodeLengths) { + codeLengthFrequencies[code.toInt() and 31]++ + } + + val codeLengthTree = buildHuffmanTreeFromFrequencies(codeLengthFrequencies, 7).tree + val numCodeLengthCodes = countCodeLengthCodes(codeLengthTree) + val headerCost = 14 + 3 * numCodeLengthCodes + + calculateCodeLength(codeLengthFrequencies, codeLengthTree) + + 2 * codeLengthFrequencies[16] + + 3 * codeLengthFrequencies[17] + + 7 * codeLengthFrequencies[18] + return tokenCost + headerCost +} + +private fun matchBitCost( + length: Int, + distance: Int, + lengthCosts: IntArray, + distanceCosts: IntArray, +): Int { + val lengthSymbol = FIXED_LENGTH_REVERSE_LOOKUP[length] and 31 + val distanceSymbol = FIXED_DISTANCE_REVERSE_LOOKUP[distance] and 31 + return lengthCosts[lengthSymbol] + distanceCosts[distanceSymbol] +} + internal fun fixedLiteralBitCost(literal: Int): Int { return FIXED_LENGTH_TREE[literal].toInt() and 0xFF } internal fun fixedMatchBitCost(length: Int, distance: Int): Int { - val lengthSymbol = FIXED_LENGTH_REVERSE_LOOKUP[length] and 31 - val distanceSymbol = FIXED_DISTANCE_REVERSE_LOOKUP[distance] and 31 - return (FIXED_LENGTH_TREE[257 + lengthSymbol].toInt() and 0xFF) + - (FIXED_LENGTH_EXTRA_BITS[lengthSymbol].toInt() and 0xFF) + - (FIXED_DISTANCE_TREE[distanceSymbol].toInt() and 0xFF) + - (FIXED_DISTANCE_EXTRA_BITS[distanceSymbol].toInt() and 0xFF) + return matchBitCost(length, distance, FIXED_LENGTH_COSTS, FIXED_DISTANCE_COSTS) } // Bound memory without forcing matches to stop at a window boundary. internal const val COST_AWARE_WINDOW_SIZE = 262_144 +private const val COST_AWARE_DYNAMIC_MIN_WINDOW = 1_024 // Price every short match length plus the longest available match. private const val COST_AWARE_LENGTH_SEARCH = 64 + +private val FIXED_LITERAL_COSTS = IntArray(288) { + FIXED_LENGTH_TREE[it].toInt() and 0xFF +} + +private val FIXED_LENGTH_COSTS = IntArray(31) { symbol -> + (FIXED_LENGTH_TREE[257 + symbol].toInt() and 0xFF) + + (FIXED_LENGTH_EXTRA_BITS[symbol].toInt() and 0xFF) +} + +private val FIXED_DISTANCE_COSTS = IntArray(31) { symbol -> + (FIXED_DISTANCE_TREE[symbol].toInt() and 0xFF) + + (FIXED_DISTANCE_EXTRA_BITS[symbol].toInt() and 0xFF) +} diff --git a/kflate/src/commonMain/kotlin/com/rafambn/kflate/huffman/HuffmanCode.kt b/kflate/src/commonMain/kotlin/com/rafambn/kflate/huffman/HuffmanCode.kt index 427985e..64f3d70 100644 --- a/kflate/src/commonMain/kotlin/com/rafambn/kflate/huffman/HuffmanCode.kt +++ b/kflate/src/commonMain/kotlin/com/rafambn/kflate/huffman/HuffmanCode.kt @@ -148,7 +148,7 @@ internal fun buildHuffmanTreeFromFrequencies(frequencies: IntArray, maxBits: Int nodes.sortBy { it.frequency } val combinedNodes = ArrayList(nodes) - combinedNodes.add(HuffmanNode(symbol = -1, frequency = 25001)) + combinedNodes.add(HuffmanNode(symbol = -1, frequency = Int.MAX_VALUE)) var lowFreqIndex = 0 var highFreqIndex = 1 diff --git a/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt b/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt index 8937532..1ddcd19 100644 --- a/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt +++ b/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt @@ -272,6 +272,22 @@ class AlgorithmCoverageTest { assertEquals(4, choices[1]) } + @Test + fun costAwareParsingRepricesRareMatchesWithDynamicTrees() { + val data = ByteArray(2_048) + for (symbol in 1..255) { + data[symbol + 2] = symbol.toByte() + } + val matches = IntArray(data.size) + matches[0] = (3 shl MATCH_DISTANCE_BITS) or 1 + val costs = IntArray(data.size + 1) + val choices = IntArray(data.size) + + chooseCostAwarePath(data, 0, data.size, matches, costs, choices) + + assertEquals(1, choices[0]) + } + @Test fun costAwareLevelRoundTripsWindowsAndDictionaries() { val multipleWindows = ByteArray(COST_AWARE_WINDOW_SIZE * 2 + 3) @@ -304,6 +320,10 @@ class AlgorithmCoverageTest { assertEquals(0, buildHuffmanTreeFromFrequencies(IntArray(4), 3).maxBits) assertEquals(1, buildHuffmanTreeFromFrequencies(intArrayOf(0, 7), 3).maxBits) + val highFrequencyTree = buildHuffmanTreeFromFrequencies(IntArray(4) { 30_000 }, 15) + assertEquals(2, highFrequencyTree.maxBits) + assertTrue(highFrequencyTree.tree.all { it.toInt() == 2 }) + val limited = buildHuffmanTreeFromFrequencies( intArrayOf(1, 1, 2, 3, 5, 8, 13, 21), 3, diff --git a/performance/2026-09-09-dynamic/RESULTS.md b/performance/2026-09-09-dynamic/RESULTS.md new file mode 100644 index 0000000..4c8ce62 --- /dev/null +++ b/performance/2026-09-09-dynamic/RESULTS.md @@ -0,0 +1,58 @@ +# Refine level 9 parsing with dynamic Huffman prices + +Build Huffman prices from the fixed-cost parse, try one dynamic-cost refinement, and keep it only if the rebuilt full-window estimate improves. This reduces actual level 9 output in all changed fixtures. It adds a second parsing pass and scratch allocations. The estimate spans a parser window, which may become multiple encoded blocks, so it is not a guarantee against output regressions on arbitrary inputs. The Huffman builder sentinel changes to Int.MAX_VALUE because window frequencies can exceed its old 25001 bound. + +Base: `fe2ff51`, `dev-1.1.0`. Measured on September 9, 2026 on Linux x86_64, Intel Core i7-11800H. JVM uses JBR 17.0.14; Node uses 22.22.1. + +Only KFlate was timed. Kompress sizes and timings come unchanged from the trusted September 8 archive in `performance/history.json`. Benchmark setup may produce Kompress streams for decoder validation outside timing. + +## Compressed size + +The JVM sweep compresses all seven tracked corpora at every listed level. Every output must round-trip through both the JDK RAW inflater and KFlate. Byte counts are deterministic. Single-run durations in the sweep JSON are diagnostic, not throughput benchmarks. + +Output reduction is `(beforeBytes - afterBytes) / beforeBytes`. Totals weight each corpus by its compressed bytes; they are not averages of percentage changes. + +| Level | Before bytes | After bytes | Output reduction | +| ---: | ---: | ---: | ---: | +| 9 | 37,251,418 | 36,780,911 | 1.2631% | + +### Level 9 + +| Corpus | Before bytes | After bytes | Reduction | Saved JVM Kompress bytes | +| --- | ---: | ---: | ---: | ---: | +| simpleText | 84 | 84 | 0.0000% | 84 | +| text | 492,523 | 488,094 | 0.8992% | 503,400 | +| model3D | 2,153 | 2,153 | 0.0000% | 2,149 | +| Rainier.bmp | 3,258,570 | 3,255,198 | 0.1035% | 3,270,382 | +| Maltese.bmp | 7,034,092 | 6,860,004 | 2.4749% | 7,090,887 | +| Sunrise.bmp | 26,372,269 | 26,083,978 | 1.0932% | 26,652,810 | +| compressed_MVT.pbf | 91,727 | 91,400 | 0.3565% | 91,400 | + +## Compression timing + +Development measurements use three one-second warmups and five one-second measurement iterations. JVM has one fresh fork per corpus; Native has one process per corpus; Wasm uses one runner. These shorter runs detect broad tradeoffs and are not release-grade speed claims. Raw samples, errors and confidence intervals are retained. No decompression speed claim is made. + +### jvm, level 9 + +| Corpus | Before ms | After ms | Before/after speedup | Saved Kompress/after speedup | +| --- | ---: | ---: | ---: | ---: | +| simpleText | 0.0272 | 0.0273 | 0.996x | 0.148x | +| text | 192.2328 | 194.8697 | 0.986x | 0.382x | +| model3D | 0.0969 | 0.1522 | 0.637x | 0.197x | +| Rainier.bmp | 2551.1684 | 2882.2180 | 0.885x | 0.038x | +| Maltese.bmp | 1206.9043 | 1639.5376 | 0.736x | 0.242x | +| Sunrise.bmp | 11385.8072 | 13942.4601 | 0.817x | 0.121x | +| compressed_MVT.pbf | 9.3247 | 10.8204 | 0.862x | 0.384x | + + +## Validation and reproduction + +Linux JVM tests passed, including multiple parser windows, dictionaries, and high Huffman frequencies. All seven level 9 fixture outputs passed both JDK and KFlate decoding and had no size regressions. All seven level 9 JMH compression cases completed. No Native or Wasm timing claim is made. + +Tracked source diff SHA-256: `c5ac518b7849a2fe92ae788dff7a5c162a4bf520a3c819051959a652e01b5c0d`. Added source/test files are present in this commit. + +Linux build: `ANDROID_HOME=/home/rafael/Android/Sdk ./gradlew :kflate:jvmTest :kflate:jvmBenchmarkBenchmarkJar --no-parallel --max-workers=1`. + +For level 9 timing, set `BENCHMARK_COMPRESSION_LEVEL` to 9 in `BenchmarkState.kt` before building; leave it at 6 otherwise. Use JBR 17.0.14 and the generated JMH jar with the main and benchmark classes on its classpath. Run `org.openjdk.jmh.Main` with the relevant `CompressionBenchmarks` method filter and `-wi 3 -i 5 -w 1s -r 1s -f 1 -foe true -rf json -rff result.json`. Only KFlate benchmark methods should be selected. + +Compile `RatioSweep.java` against the KFlate classes and generated benchmark jar, then run it with `kflate/src/jvmTest/resources FIRST_LEVEL LAST_LEVEL`. It checks both JDK and KFlate decompression and records deterministic sizes and output hashes. diff --git a/performance/2026-09-09-dynamic/RatioSweep.java b/performance/2026-09-09-dynamic/RatioSweep.java new file mode 100644 index 0000000..2d3bf10 --- /dev/null +++ b/performance/2026-09-09-dynamic/RatioSweep.java @@ -0,0 +1,39 @@ +import com.rafambn.kflate.KFlate; +import com.rafambn.kflate.compression.Raw; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.security.MessageDigest; +import java.util.HexFormat; +import java.util.zip.Inflater; + +public class RatioSweep { + public static void main(String[] args) throws Exception { + String[] names = {"simpleText", "text", "model3D", "Rainier.bmp", "Maltese.bmp", "Sunrise.bmp", "compressed_MVT.pbf"}; + int first = args.length > 1 ? Integer.parseInt(args[1]) : 0; + int last = args.length > 2 ? Integer.parseInt(args[2]) : 9; + for (String name : names) { + byte[] input = Files.readAllBytes(Path.of(args[0], name)); + for (int level = first; level <= last; level++) { + long start = System.nanoTime(); + byte[] output = KFlate.INSTANCE.compress(input, new Raw(level, null)); + double ms = (System.nanoTime() - start) / 1e6; + Inflater inflater = new Inflater(true); + try { + inflater.setInput(output); + byte[] decoded = new byte[input.length + 1]; + int count = inflater.inflate(decoded); + if (!inflater.finished() || count != input.length || !Arrays.equals(input, Arrays.copyOf(decoded, count))) { + throw new AssertionError("Invalid output: " + name + " level " + level); + } + } finally { + inflater.end(); + } + if (!Arrays.equals(input, KFlate.INSTANCE.decompress(output, new com.rafambn.kflate.decompression.Raw(null, null)))) { + throw new AssertionError("KFlate round trip: " + name + " level " + level); + } + System.out.printf(java.util.Locale.ROOT, "{\"corpus\":\"%s\",\"level\":%d,\"originalSizeBytes\":%d,\"compressedSizeBytes\":%d,\"singleRunMs\":%.6f,\"sha256\":\"%s\"}%n", name, level, input.length, output.length, ms, HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(output))); + } + } + } +} diff --git a/performance/2026-09-09-dynamic/after-jmh.json b/performance/2026-09-09-dynamic/after-jmh.json new file mode 100644 index 0000000..791c638 --- /dev/null +++ b/performance/2026-09-09-dynamic/after-jmh.json @@ -0,0 +1,380 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "simpleText" + }, + "primaryMetric" : { + "score" : 2.7320152206656796E-5, + "scoreError" : 3.193239556325176E-6, + "scoreConfidence" : [ + 2.412691265033162E-5, + 3.0513391762981973E-5 + ], + "scorePercentiles" : { + "0.0" : 2.633724002001264E-5, + "50.0" : 2.790806473394905E-5, + "90.0" : 2.794377153474337E-5, + "95.0" : 2.794377153474337E-5, + "99.0" : 2.794377153474337E-5, + "99.9" : 2.794377153474337E-5, + "99.99" : 2.794377153474337E-5, + "99.999" : 2.794377153474337E-5, + "99.9999" : 2.794377153474337E-5, + "100.0" : 2.794377153474337E-5 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 2.790806473394905E-5, + 2.794377153474337E-5, + 2.792138082742449E-5, + 2.633724002001264E-5, + 2.6490303917154435E-5 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "text" + }, + "primaryMetric" : { + "score" : 0.194869724, + "scoreError" : 0.0023549891095648906, + "scoreConfidence" : [ + 0.1925147348904351, + 0.19722471310956488 + ], + "scorePercentiles" : { + "0.0" : 0.1941997665, + "50.0" : 0.19475896616666666, + "90.0" : 0.1957748385, + "95.0" : 0.1957748385, + "99.0" : 0.1957748385, + "99.9" : 0.1957748385, + "99.99" : 0.1957748385, + "99.999" : 0.1957748385, + "99.9999" : 0.1957748385, + "100.0" : 0.1957748385 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.1957748385, + 0.19475896616666666, + 0.19448499083333334, + 0.1941997665, + 0.195130058 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "model3D" + }, + "primaryMetric" : { + "score" : 1.5216298784283998E-4, + "scoreError" : 2.6134056259282696E-6, + "scoreConfidence" : [ + 1.495495822169117E-4, + 1.5477639346876825E-4 + ], + "scorePercentiles" : { + "0.0" : 1.515940239466505E-4, + "50.0" : 1.518362144808743E-4, + "90.0" : 1.5320168433144432E-4, + "95.0" : 1.5320168433144432E-4, + "99.0" : 1.5320168433144432E-4, + "99.9" : 1.5320168433144432E-4, + "99.99" : 1.5320168433144432E-4, + "99.999" : 1.5320168433144432E-4, + "99.9999" : 1.5320168433144432E-4, + "100.0" : 1.5320168433144432E-4 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 1.518362144808743E-4, + 1.5249330899390245E-4, + 1.5320168433144432E-4, + 1.515940239466505E-4, + 1.5168970746132847E-4 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Rainier.bmp" + }, + "primaryMetric" : { + "score" : 2.8822180459999998, + "scoreError" : 0.6147377532845272, + "scoreConfidence" : [ + 2.2674802927154727, + 3.496955799284527 + ], + "scorePercentiles" : { + "0.0" : 2.598949862, + "50.0" : 2.943511252, + "90.0" : 2.985083897, + "95.0" : 2.985083897, + "99.0" : 2.985083897, + "99.9" : 2.985083897, + "99.99" : 2.985083897, + "99.999" : 2.985083897, + "99.9999" : 2.985083897, + "100.0" : 2.985083897 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 2.598949862, + 2.953478858, + 2.930066361, + 2.943511252, + 2.985083897 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Maltese.bmp" + }, + "primaryMetric" : { + "score" : 1.6395375802, + "scoreError" : 0.05287466499250389, + "scoreConfidence" : [ + 1.5866629152074962, + 1.6924122451925039 + ], + "scorePercentiles" : { + "0.0" : 1.620594794, + "50.0" : 1.635996985, + "90.0" : 1.653876066, + "95.0" : 1.653876066, + "99.0" : 1.653876066, + "99.9" : 1.653876066, + "99.99" : 1.653876066, + "99.999" : 1.653876066, + "99.9999" : 1.653876066, + "100.0" : 1.653876066 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 1.653876066, + 1.652097568, + 1.620594794, + 1.635122488, + 1.635996985 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Sunrise.bmp" + }, + "primaryMetric" : { + "score" : 13.942460108199999, + "scoreError" : 2.7906046247424645, + "scoreConfidence" : [ + 11.151855483457535, + 16.733064732942463 + ], + "scorePercentiles" : { + "0.0" : 12.6595252, + "50.0" : 14.215782169, + "90.0" : 14.441000896, + "95.0" : 14.441000896, + "99.0" : 14.441000896, + "99.9" : 14.441000896, + "99.99" : 14.441000896, + "99.999" : 14.441000896, + "99.9999" : 14.441000896, + "100.0" : 14.441000896 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 12.6595252, + 14.441000896, + 14.220994907, + 14.174997369, + 14.215782169 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "compressed_MVT.pbf" + }, + "primaryMetric" : { + "score" : 0.010820364386623128, + "scoreError" : 0.002525898538605477, + "scoreConfidence" : [ + 0.008294465848017652, + 0.013346262925228605 + ], + "scorePercentiles" : { + "0.0" : 0.010376159041237114, + "50.0" : 0.010399470639175257, + "90.0" : 0.011875508952941177, + "95.0" : 0.011875508952941177, + "99.0" : 0.011875508952941177, + "99.9" : 0.011875508952941177, + "99.99" : 0.011875508952941177, + "99.999" : 0.011875508952941177, + "99.9999" : 0.011875508952941177, + "100.0" : 0.011875508952941177 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.011875508952941177, + 0.011053454846153846, + 0.010399470639175257, + 0.010376159041237114, + 0.010397228453608248 + ] + ] + }, + "secondaryMetrics" : { + } + } +] diff --git a/performance/2026-09-09-dynamic/after-sizes.jsonl b/performance/2026-09-09-dynamic/after-sizes.jsonl new file mode 100644 index 0000000..80e29dd --- /dev/null +++ b/performance/2026-09-09-dynamic/after-sizes.jsonl @@ -0,0 +1,7 @@ +{"corpus":"simpleText","level":9,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":33.087246,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"text","level":9,"originalSizeBytes":1232923,"compressedSizeBytes":488094,"singleRunMs":293.477464,"sha256":"39f6f3af429bf689a09a37bb94a1ac4ea5d368251814af5ce5ae54c9e09e8f2f"} +{"corpus":"model3D","level":9,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":2.537058,"sha256":"450f6437d13a19585d0df05da961baf30023451a17612fd84a683a2f2f450ea7"} +{"corpus":"Rainier.bmp","level":9,"originalSizeBytes":6220854,"compressedSizeBytes":3255198,"singleRunMs":4203.219682,"sha256":"e67eda98521873e7a12e80ef1c3e298e342000a7b16a0d297a599a2f3bf7cf80"} +{"corpus":"Maltese.bmp","level":9,"originalSizeBytes":16427390,"compressedSizeBytes":6860004,"singleRunMs":1710.326159,"sha256":"82d5f7e47a65a6f9f9d47068438b5472ec68cd2b6ba1827f93d7dd18a6ce0083"} +{"corpus":"Sunrise.bmp","level":9,"originalSizeBytes":52344054,"compressedSizeBytes":26083978,"singleRunMs":14579.570679,"sha256":"c0bb6198bb9ef637a1cc6bb3007c1ea2b4be493fa772ee4312e47d2fe05ab57c"} +{"corpus":"compressed_MVT.pbf","level":9,"originalSizeBytes":146224,"compressedSizeBytes":91400,"singleRunMs":12.682059,"sha256":"c3f8bcf3e6f73717dc8b242e96b3324b9f0b30dfe2e06fbb8e56f89128c22adb"} diff --git a/performance/2026-09-09-dynamic/before-jmh.json b/performance/2026-09-09-dynamic/before-jmh.json new file mode 100644 index 0000000..7d236a0 --- /dev/null +++ b/performance/2026-09-09-dynamic/before-jmh.json @@ -0,0 +1,380 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "simpleText" + }, + "primaryMetric" : { + "score" : 2.7203772831719315E-5, + "scoreError" : 2.4728033893405515E-6, + "scoreConfidence" : [ + 2.4730969442378765E-5, + 2.9676576221059866E-5 + ], + "scorePercentiles" : { + "0.0" : 2.6647192353803117E-5, + "50.0" : 2.6857865060823332E-5, + "90.0" : 2.81695109283461E-5, + "95.0" : 2.81695109283461E-5, + "99.0" : 2.81695109283461E-5, + "99.9" : 2.81695109283461E-5, + "99.99" : 2.81695109283461E-5, + "99.999" : 2.81695109283461E-5, + "99.9999" : 2.81695109283461E-5, + "100.0" : 2.81695109283461E-5 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 2.81695109283461E-5, + 2.679433043990784E-5, + 2.6857865060823332E-5, + 2.7549965375716175E-5, + 2.6647192353803117E-5 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "text" + }, + "primaryMetric" : { + "score" : 0.19223283826666665, + "scoreError" : 0.004608719940206378, + "scoreConfidence" : [ + 0.18762411832646028, + 0.19684155820687302 + ], + "scorePercentiles" : { + "0.0" : 0.19101506583333333, + "50.0" : 0.1922419345, + "90.0" : 0.19371265383333333, + "95.0" : 0.19371265383333333, + "99.0" : 0.19371265383333333, + "99.9" : 0.19371265383333333, + "99.99" : 0.19371265383333333, + "99.999" : 0.19371265383333333, + "99.9999" : 0.19371265383333333, + "100.0" : 0.19371265383333333 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.19101506583333333, + 0.1910922, + 0.1922419345, + 0.19310233716666667, + 0.19371265383333333 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "model3D" + }, + "primaryMetric" : { + "score" : 9.687598398050543E-5, + "scoreError" : 4.441203208452849E-6, + "scoreConfidence" : [ + 9.243478077205258E-5, + 1.0131718718895828E-4 + ], + "scorePercentiles" : { + "0.0" : 9.524352980384688E-5, + "50.0" : 9.690634576632436E-5, + "90.0" : 9.838484753098564E-5, + "95.0" : 9.838484753098564E-5, + "99.0" : 9.838484753098564E-5, + "99.9" : 9.838484753098564E-5, + "99.99" : 9.838484753098564E-5, + "99.999" : 9.838484753098564E-5, + "99.9999" : 9.838484753098564E-5, + "100.0" : 9.838484753098564E-5 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 9.524352980384688E-5, + 9.838484753098564E-5, + 9.690634576632436E-5, + 9.735513304136253E-5, + 9.649006376000771E-5 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Rainier.bmp" + }, + "primaryMetric" : { + "score" : 2.551168353, + "scoreError" : 0.5400113148623004, + "scoreConfidence" : [ + 2.0111570381376995, + 3.0911796678623005 + ], + "scorePercentiles" : { + "0.0" : 2.474772922, + "50.0" : 2.500730151, + "90.0" : 2.800922797, + "95.0" : 2.800922797, + "99.0" : 2.800922797, + "99.9" : 2.800922797, + "99.99" : 2.800922797, + "99.999" : 2.800922797, + "99.9999" : 2.800922797, + "100.0" : 2.800922797 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 2.500730151, + 2.503046614, + 2.474772922, + 2.476369281, + 2.800922797 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Maltese.bmp" + }, + "primaryMetric" : { + "score" : 1.2069042516, + "scoreError" : 0.07625138081262017, + "scoreConfidence" : [ + 1.1306528707873797, + 1.28315563241262 + ], + "scorePercentiles" : { + "0.0" : 1.190969672, + "50.0" : 1.196923624, + "90.0" : 1.234775154, + "95.0" : 1.234775154, + "99.0" : 1.234775154, + "99.9" : 1.234775154, + "99.99" : 1.234775154, + "99.999" : 1.234775154, + "99.9999" : 1.234775154, + "100.0" : 1.234775154 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 1.220696166, + 1.234775154, + 1.191156642, + 1.196923624, + 1.190969672 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "Sunrise.bmp" + }, + "primaryMetric" : { + "score" : 11.385807222599999, + "scoreError" : 0.6233573844313627, + "scoreConfidence" : [ + 10.762449838168635, + 12.009164607031362 + ], + "scorePercentiles" : { + "0.0" : 11.255930507, + "50.0" : 11.289084607, + "90.0" : 11.570045612, + "95.0" : 11.570045612, + "99.0" : 11.570045612, + "99.9" : 11.570045612, + "99.99" : 11.570045612, + "99.999" : 11.570045612, + "99.9999" : 11.570045612, + "100.0" : 11.570045612 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 11.570045612, + 11.554908951, + 11.289084607, + 11.255930507, + 11.259066436 + ] + ] + }, + "secondaryMetrics" : { + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "com.rafambn.kflate.benchmark.CompressionBenchmarks.rawDeflateCompression", + "mode" : "avgt", + "threads" : 1, + "forks" : 1, + "jvm" : "/home/rafael/.jdks/jbr-17.0.14/bin/java", + "jvmArgs" : [ + ], + "jdkVersion" : "17.0.14", + "vmName" : "OpenJDK 64-Bit Server VM", + "vmVersion" : "17.0.14+1-b1367.22", + "warmupIterations" : 3, + "warmupTime" : "1 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "params" : { + "corpus" : "compressed_MVT.pbf" + }, + "primaryMetric" : { + "score" : 0.009324682879700792, + "scoreError" : 4.5141358132523053E-4, + "scoreConfidence" : [ + 0.008873269298375562, + 0.009776096461026023 + ], + "scorePercentiles" : { + "0.0" : 0.00922847810091743, + "50.0" : 0.009319085546296296, + "90.0" : 0.009516081198113207, + "95.0" : 0.009516081198113207, + "99.0" : 0.009516081198113207, + "99.9" : 0.009516081198113207, + "99.99" : 0.009516081198113207, + "99.999" : 0.009516081198113207, + "99.9999" : 0.009516081198113207, + "100.0" : 0.009516081198113207 + }, + "scoreUnit" : "s/op", + "rawData" : [ + [ + 0.009516081198113207, + 0.00922847810091743, + 0.009229693256880734, + 0.009330076296296296, + 0.009319085546296296 + ] + ] + }, + "secondaryMetrics" : { + } + } +] diff --git a/performance/2026-09-09-dynamic/before-sizes.jsonl b/performance/2026-09-09-dynamic/before-sizes.jsonl new file mode 100644 index 0000000..6b0a261 --- /dev/null +++ b/performance/2026-09-09-dynamic/before-sizes.jsonl @@ -0,0 +1,70 @@ +{"corpus":"simpleText","level":0,"originalSizeBytes":100,"compressedSizeBytes":105,"singleRunMs":18.721607} +{"corpus":"simpleText","level":1,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":10.375607} +{"corpus":"simpleText","level":2,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.346866} +{"corpus":"simpleText","level":3,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.426491} +{"corpus":"simpleText","level":4,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.288781} +{"corpus":"simpleText","level":5,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.294199} +{"corpus":"simpleText","level":6,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.256687} +{"corpus":"simpleText","level":7,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.217747} +{"corpus":"simpleText","level":8,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.213022} +{"corpus":"simpleText","level":9,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.510794} +{"corpus":"text","level":0,"originalSizeBytes":1232923,"compressedSizeBytes":1233018,"singleRunMs":4.634060} +{"corpus":"text","level":1,"originalSizeBytes":1232923,"compressedSizeBytes":599813,"singleRunMs":54.476717} +{"corpus":"text","level":2,"originalSizeBytes":1232923,"compressedSizeBytes":581519,"singleRunMs":33.454095} +{"corpus":"text","level":3,"originalSizeBytes":1232923,"compressedSizeBytes":565252,"singleRunMs":34.883134} +{"corpus":"text","level":4,"originalSizeBytes":1232923,"compressedSizeBytes":531466,"singleRunMs":59.907435} +{"corpus":"text","level":5,"originalSizeBytes":1232923,"compressedSizeBytes":521837,"singleRunMs":61.611316} +{"corpus":"text","level":6,"originalSizeBytes":1232923,"compressedSizeBytes":506455,"singleRunMs":76.163221} +{"corpus":"text","level":7,"originalSizeBytes":1232923,"compressedSizeBytes":506097,"singleRunMs":78.619466} +{"corpus":"text","level":8,"originalSizeBytes":1232923,"compressedSizeBytes":513489,"singleRunMs":83.872443} +{"corpus":"text","level":9,"originalSizeBytes":1232923,"compressedSizeBytes":492523,"singleRunMs":220.517381} +{"corpus":"model3D","level":0,"originalSizeBytes":2478,"compressedSizeBytes":2483,"singleRunMs":0.054391} +{"corpus":"model3D","level":1,"originalSizeBytes":2478,"compressedSizeBytes":2169,"singleRunMs":0.236631} +{"corpus":"model3D","level":2,"originalSizeBytes":2478,"compressedSizeBytes":2168,"singleRunMs":0.159924} +{"corpus":"model3D","level":3,"originalSizeBytes":2478,"compressedSizeBytes":2166,"singleRunMs":0.143489} +{"corpus":"model3D","level":4,"originalSizeBytes":2478,"compressedSizeBytes":2165,"singleRunMs":0.133548} +{"corpus":"model3D","level":5,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.726203} +{"corpus":"model3D","level":6,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.277670} +{"corpus":"model3D","level":7,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.243557} +{"corpus":"model3D","level":8,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.184029} +{"corpus":"model3D","level":9,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.404074} +{"corpus":"Rainier.bmp","level":0,"originalSizeBytes":6220854,"compressedSizeBytes":6221329,"singleRunMs":4.097972} +{"corpus":"Rainier.bmp","level":1,"originalSizeBytes":6220854,"compressedSizeBytes":3387685,"singleRunMs":127.041113} +{"corpus":"Rainier.bmp","level":2,"originalSizeBytes":6220854,"compressedSizeBytes":3357387,"singleRunMs":101.260474} +{"corpus":"Rainier.bmp","level":3,"originalSizeBytes":6220854,"compressedSizeBytes":3345679,"singleRunMs":106.363578} +{"corpus":"Rainier.bmp","level":4,"originalSizeBytes":6220854,"compressedSizeBytes":3325593,"singleRunMs":100.669595} +{"corpus":"Rainier.bmp","level":5,"originalSizeBytes":6220854,"compressedSizeBytes":3313388,"singleRunMs":105.538266} +{"corpus":"Rainier.bmp","level":6,"originalSizeBytes":6220854,"compressedSizeBytes":3283450,"singleRunMs":113.997284} +{"corpus":"Rainier.bmp","level":7,"originalSizeBytes":6220854,"compressedSizeBytes":3282047,"singleRunMs":120.376039} +{"corpus":"Rainier.bmp","level":8,"originalSizeBytes":6220854,"compressedSizeBytes":3274905,"singleRunMs":118.865381} +{"corpus":"Rainier.bmp","level":9,"originalSizeBytes":6220854,"compressedSizeBytes":3258570,"singleRunMs":3625.149389} +{"corpus":"Maltese.bmp","level":0,"originalSizeBytes":16427390,"compressedSizeBytes":16428645,"singleRunMs":6.704834} +{"corpus":"Maltese.bmp","level":1,"originalSizeBytes":16427390,"compressedSizeBytes":8344362,"singleRunMs":287.839174} +{"corpus":"Maltese.bmp","level":2,"originalSizeBytes":16427390,"compressedSizeBytes":7762283,"singleRunMs":334.470960} +{"corpus":"Maltese.bmp","level":3,"originalSizeBytes":16427390,"compressedSizeBytes":7494606,"singleRunMs":371.202987} +{"corpus":"Maltese.bmp","level":4,"originalSizeBytes":16427390,"compressedSizeBytes":7272625,"singleRunMs":395.378098} +{"corpus":"Maltese.bmp","level":5,"originalSizeBytes":16427390,"compressedSizeBytes":7265831,"singleRunMs":509.528066} +{"corpus":"Maltese.bmp","level":6,"originalSizeBytes":16427390,"compressedSizeBytes":7158472,"singleRunMs":523.034253} +{"corpus":"Maltese.bmp","level":7,"originalSizeBytes":16427390,"compressedSizeBytes":7157735,"singleRunMs":526.984351} +{"corpus":"Maltese.bmp","level":8,"originalSizeBytes":16427390,"compressedSizeBytes":7125327,"singleRunMs":524.641283} +{"corpus":"Maltese.bmp","level":9,"originalSizeBytes":16427390,"compressedSizeBytes":7034092,"singleRunMs":1436.734506} +{"corpus":"Sunrise.bmp","level":0,"originalSizeBytes":52344054,"compressedSizeBytes":52348049,"singleRunMs":31.612486} +{"corpus":"Sunrise.bmp","level":1,"originalSizeBytes":52344054,"compressedSizeBytes":27793016,"singleRunMs":887.391514} +{"corpus":"Sunrise.bmp","level":2,"originalSizeBytes":52344054,"compressedSizeBytes":27471887,"singleRunMs":1064.576845} +{"corpus":"Sunrise.bmp","level":3,"originalSizeBytes":52344054,"compressedSizeBytes":27404419,"singleRunMs":1166.086238} +{"corpus":"Sunrise.bmp","level":4,"originalSizeBytes":52344054,"compressedSizeBytes":27107867,"singleRunMs":1250.581032} +{"corpus":"Sunrise.bmp","level":5,"originalSizeBytes":52344054,"compressedSizeBytes":27096750,"singleRunMs":1511.964986} +{"corpus":"Sunrise.bmp","level":6,"originalSizeBytes":52344054,"compressedSizeBytes":26838825,"singleRunMs":1479.025315} +{"corpus":"Sunrise.bmp","level":7,"originalSizeBytes":52344054,"compressedSizeBytes":26827604,"singleRunMs":1687.182227} +{"corpus":"Sunrise.bmp","level":8,"originalSizeBytes":52344054,"compressedSizeBytes":26728454,"singleRunMs":1866.351752} +{"corpus":"Sunrise.bmp","level":9,"originalSizeBytes":52344054,"compressedSizeBytes":26372269,"singleRunMs":12143.996321} +{"corpus":"compressed_MVT.pbf","level":0,"originalSizeBytes":146224,"compressedSizeBytes":146239,"singleRunMs":0.056884} +{"corpus":"compressed_MVT.pbf","level":1,"originalSizeBytes":146224,"compressedSizeBytes":95812,"singleRunMs":2.498114} +{"corpus":"compressed_MVT.pbf","level":2,"originalSizeBytes":146224,"compressedSizeBytes":94608,"singleRunMs":2.921274} +{"corpus":"compressed_MVT.pbf","level":3,"originalSizeBytes":146224,"compressedSizeBytes":94345,"singleRunMs":3.426504} +{"corpus":"compressed_MVT.pbf","level":4,"originalSizeBytes":146224,"compressedSizeBytes":93369,"singleRunMs":3.443246} +{"corpus":"compressed_MVT.pbf","level":5,"originalSizeBytes":146224,"compressedSizeBytes":93229,"singleRunMs":3.893521} +{"corpus":"compressed_MVT.pbf","level":6,"originalSizeBytes":146224,"compressedSizeBytes":92605,"singleRunMs":4.154555} +{"corpus":"compressed_MVT.pbf","level":7,"originalSizeBytes":146224,"compressedSizeBytes":92610,"singleRunMs":4.015288} +{"corpus":"compressed_MVT.pbf","level":8,"originalSizeBytes":146224,"compressedSizeBytes":92631,"singleRunMs":4.439951} +{"corpus":"compressed_MVT.pbf","level":9,"originalSizeBytes":146224,"compressedSizeBytes":91727,"singleRunMs":8.610094} diff --git a/performance/2026-09-09-dynamic/native_bench.py b/performance/2026-09-09-dynamic/native_bench.py new file mode 100644 index 0000000..7a66ddc --- /dev/null +++ b/performance/2026-09-09-dynamic/native_bench.py @@ -0,0 +1,38 @@ +import json +from pathlib import Path +import subprocess +import sys + +binary = str(Path(sys.argv[1]).resolve()) +directory = Path(sys.argv[2]).resolve() +directory.mkdir(parents=True, exist_ok=True) +config = directory / 'runner.cfg' +config.write_text('\n'.join([ + 'name:ratio', f'reportFile:{directory}/benchmark.json', + 'traceFormat:text', 'reportFormat:json', + 'include:' + (sys.argv[5] if len(sys.argv) > 5 else '.*CompressionBenchmarks.rawDeflateCompression'), + f'warmups:{sys.argv[3] if len(sys.argv) > 3 else 3}', + f'iterations:{sys.argv[4] if len(sys.argv) > 4 else 5}', + 'iterationTime:1', 'iterationTimeUnit:sec', + 'outputTimeUnit:sec', 'mode:avgt', +])) + +def run(action, *args): + subprocess.run([binary, str(config), action, str(directory / 'trace.xml'), *map(str, args)], check=True) + +run('--list', directory) +configs = sorted(directory.glob('*.txt')) +expected = 14 if len(sys.argv) > 5 and 'Decompression' in sys.argv[5] else 7 +assert len(configs) == expected, configs +results = [] +for benchmark_config in configs: + samples = benchmark_config.with_suffix('.samples') + run('--benchmark', benchmark_config, samples) + values = samples.read_text().strip() + assert values and 'null' not in values + results.append(f'{benchmark_config}: {values}') +combined = directory / 'results' +combined.write_text('\n'.join(results)) +run('--store-results', combined) +rows = json.loads((directory / 'benchmark.json').read_text()) +assert len(rows) == expected From dae3c450a9f3af1e96c8f0e285150789c9832b5f Mon Sep 17 00:00:00 2001 From: rafambn Date: Wed, 9 Sep 2026 02:18:32 -0300 Subject: [PATCH 2/2] Reject two-byte no-match results at parser window boundaries --- .../rafambn/kflate/algorithm/DeflateCost.kt | 2 +- .../jvmTest/kotlin/AlgorithmCoverageTest.kt | 22 ++ performance/2026-09-09-dynamic/RESULTS.md | 41 ++- .../2026-09-09-dynamic/RatioSweep.java | 5 +- performance/2026-09-09-dynamic/after-jmh.json | 266 +++++++++--------- .../2026-09-09-dynamic/after-sizes.jsonl | 77 ++++- 6 files changed, 261 insertions(+), 152 deletions(-) diff --git a/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt b/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt index 25f12f7..0a45747 100644 --- a/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt +++ b/kflate/src/commonMain/kotlin/com/rafambn/kflate/algorithm/DeflateCost.kt @@ -179,7 +179,7 @@ private fun chooseCostAwarePath( } } - if (maximumLength > searchedLength) { + if (maximumLength >= 3 && maximumLength > searchedLength) { val nextCost = if (offset + maximumLength <= size) costs[offset + maximumLength] else 0 val candidateCost = matchBitCost(maximumLength, distance, lengthCosts, distanceCosts) + nextCost if (candidateCost <= bestCost) { diff --git a/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt b/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt index 1ddcd19..7171e89 100644 --- a/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt +++ b/kflate/src/jvmTest/kotlin/AlgorithmCoverageTest.kt @@ -288,6 +288,28 @@ class AlgorithmCoverageTest { assertEquals(1, choices[0]) } + @Test + fun costAwareParsingRejectsPackedTwoByteNoMatchAtWindowEnd() { + val data = ByteArray(2_048) + val matches = IntArray(data.size) + var literalSymbol = 0 + for (offset in 0 until data.size - 1) { + if (offset % 3 == 0 && offset + 3 <= data.size) { + matches[offset] = (3 shl MATCH_DISTANCE_BITS) or 1 + } else { + data[offset] = (if (literalSymbol < 255) literalSymbol++ else 0).toByte() + } + } + data[data.lastIndex] = 255.toByte() + matches[data.lastIndex] = 2 shl MATCH_DISTANCE_BITS + + val costs = IntArray(data.size + 1) + val choices = IntArray(data.size) + chooseCostAwarePath(data, 0, data.size, matches, costs, choices) + + assertEquals(1, choices[data.lastIndex]) + } + @Test fun costAwareLevelRoundTripsWindowsAndDictionaries() { val multipleWindows = ByteArray(COST_AWARE_WINDOW_SIZE * 2 + 3) diff --git a/performance/2026-09-09-dynamic/RESULTS.md b/performance/2026-09-09-dynamic/RESULTS.md index 4c8ce62..def7b7e 100644 --- a/performance/2026-09-09-dynamic/RESULTS.md +++ b/performance/2026-09-09-dynamic/RESULTS.md @@ -1,6 +1,6 @@ # Refine level 9 parsing with dynamic Huffman prices -Build Huffman prices from the fixed-cost parse, try one dynamic-cost refinement, and keep it only if the rebuilt full-window estimate improves. This reduces actual level 9 output in all changed fixtures. It adds a second parsing pass and scratch allocations. The estimate spans a parser window, which may become multiple encoded blocks, so it is not a guarantee against output regressions on arbitrary inputs. The Huffman builder sentinel changes to Int.MAX_VALUE because window frequencies can exceed its old 25001 bound. +Build Huffman prices from the fixed-cost parse, try one dynamic-cost refinement, and keep it only if the rebuilt full-window estimate improves. This adds parsing work and scratch allocations. The estimate spans a parser window, which may become multiple encoded blocks, so it does not guarantee against size regressions on arbitrary inputs. Reject candidates shorter than the DEFLATE minimum of three bytes, including the packed two-byte no-match sentinel at window boundaries. The Huffman builder sentinel becomes Int.MAX_VALUE because window frequencies can exceed 25001. Base: `fe2ff51`, `dev-1.1.0`. Measured on September 9, 2026 on Linux x86_64, Intel Core i7-11800H. JVM uses JBR 17.0.14; Node uses 22.22.1. @@ -14,8 +14,29 @@ Output reduction is `(beforeBytes - afterBytes) / beforeBytes`. Totals weight ea | Level | Before bytes | After bytes | Output reduction | | ---: | ---: | ---: | ---: | +| 0 | 76,379,868 | 76,379,868 | 0.0000% | +| 1 | 40,222,941 | 40,222,941 | 0.0000% | +| 2 | 39,269,936 | 39,269,936 | 0.0000% | +| 3 | 38,906,551 | 38,906,551 | 0.0000% | +| 4 | 38,333,169 | 38,333,169 | 0.0000% | +| 5 | 38,293,272 | 38,293,272 | 0.0000% | +| 6 | 37,882,044 | 37,882,044 | 0.0000% | +| 7 | 37,868,330 | 37,868,330 | 0.0000% | +| 8 | 37,737,043 | 37,737,043 | 0.0000% | | 9 | 37,251,418 | 36,780,911 | 1.2631% | +### Level 6 + +| Corpus | Before bytes | After bytes | Reduction | Saved JVM Kompress bytes | +| --- | ---: | ---: | ---: | ---: | +| simpleText | 84 | 84 | 0.0000% | 84 | +| text | 506,455 | 506,455 | 0.0000% | 505,318 | +| model3D | 2,153 | 2,153 | 0.0000% | 2,149 | +| Rainier.bmp | 3,283,450 | 3,283,450 | 0.0000% | 3,275,337 | +| Maltese.bmp | 7,158,472 | 7,158,472 | 0.0000% | 7,096,685 | +| Sunrise.bmp | 26,838,825 | 26,838,825 | 0.0000% | 26,698,992 | +| compressed_MVT.pbf | 92,605 | 92,605 | 0.0000% | 91,408 | + ### Level 9 | Corpus | Before bytes | After bytes | Reduction | Saved JVM Kompress bytes | @@ -36,20 +57,20 @@ Development measurements use three one-second warmups and five one-second measur | Corpus | Before ms | After ms | Before/after speedup | Saved Kompress/after speedup | | --- | ---: | ---: | ---: | ---: | -| simpleText | 0.0272 | 0.0273 | 0.996x | 0.148x | -| text | 192.2328 | 194.8697 | 0.986x | 0.382x | -| model3D | 0.0969 | 0.1522 | 0.637x | 0.197x | -| Rainier.bmp | 2551.1684 | 2882.2180 | 0.885x | 0.038x | -| Maltese.bmp | 1206.9043 | 1639.5376 | 0.736x | 0.242x | -| Sunrise.bmp | 11385.8072 | 13942.4601 | 0.817x | 0.121x | -| compressed_MVT.pbf | 9.3247 | 10.8204 | 0.862x | 0.384x | +| simpleText | 0.0272 | 0.0272 | 1.000x | 0.149x | +| text | 192.2328 | 233.2505 | 0.824x | 0.319x | +| model3D | 0.0969 | 0.1644 | 0.589x | 0.183x | +| Rainier.bmp | 2551.1684 | 2680.9962 | 0.952x | 0.041x | +| Maltese.bmp | 1206.9043 | 1650.6747 | 0.731x | 0.240x | +| Sunrise.bmp | 11385.8072 | 12729.0296 | 0.894x | 0.132x | +| compressed_MVT.pbf | 9.3247 | 11.5040 | 0.811x | 0.362x | ## Validation and reproduction -Linux JVM tests passed, including multiple parser windows, dictionaries, and high Huffman frequencies. All seven level 9 fixture outputs passed both JDK and KFlate decoding and had no size regressions. All seven level 9 JMH compression cases completed. No Native or Wasm timing claim is made. +Linux JVM tests and 100% instruction/branch coverage verification passed, including the packed two-byte boundary regression, multiple windows, dictionaries and high Huffman frequencies. All 70 corpus/level outputs passed JDK and KFlate decompression; levels 0 through 8 are unchanged and level 9 has no fixture size regressions. All seven level 9 JMH compression cases completed. The combined variant also passed all 70 cases after the minimum-length fix. No Native or Wasm timing claim is made for this standalone variant. -Tracked source diff SHA-256: `c5ac518b7849a2fe92ae788dff7a5c162a4bf520a3c819051959a652e01b5c0d`. Added source/test files are present in this commit. +Tracked source diff SHA-256: `9450056c9788829eb49cd6364321384fa4b483f912838ebe34855b1947e79591`. Added source/test files are present in this commit. Linux build: `ANDROID_HOME=/home/rafael/Android/Sdk ./gradlew :kflate:jvmTest :kflate:jvmBenchmarkBenchmarkJar --no-parallel --max-workers=1`. diff --git a/performance/2026-09-09-dynamic/RatioSweep.java b/performance/2026-09-09-dynamic/RatioSweep.java index 2d3bf10..112ba7d 100644 --- a/performance/2026-09-09-dynamic/RatioSweep.java +++ b/performance/2026-09-09-dynamic/RatioSweep.java @@ -13,6 +13,7 @@ public static void main(String[] args) throws Exception { int first = args.length > 1 ? Integer.parseInt(args[1]) : 0; int last = args.length > 2 ? Integer.parseInt(args[2]) : 9; for (String name : names) { + if (args.length > 3 && !name.equals(args[3])) continue; byte[] input = Files.readAllBytes(Path.of(args[0], name)); for (int level = first; level <= last; level++) { long start = System.nanoTime(); @@ -24,7 +25,9 @@ public static void main(String[] args) throws Exception { byte[] decoded = new byte[input.length + 1]; int count = inflater.inflate(decoded); if (!inflater.finished() || count != input.length || !Arrays.equals(input, Arrays.copyOf(decoded, count))) { - throw new AssertionError("Invalid output: " + name + " level " + level); + Files.write(Path.of("/tmp/kflate-invalid-" + name + "-" + level + ".deflate"), output); + int mismatch = Arrays.mismatch(input, Arrays.copyOf(decoded, count)); + throw new AssertionError("Invalid output: " + name + " level " + level + " decoded=" + count + " expected=" + input.length + " finished=" + inflater.finished() + " remaining=" + inflater.getRemaining() + " mismatch=" + mismatch); } } finally { inflater.end(); diff --git a/performance/2026-09-09-dynamic/after-jmh.json b/performance/2026-09-09-dynamic/after-jmh.json index 791c638..4fe58b8 100644 --- a/performance/2026-09-09-dynamic/after-jmh.json +++ b/performance/2026-09-09-dynamic/after-jmh.json @@ -21,32 +21,32 @@ "corpus" : "simpleText" }, "primaryMetric" : { - "score" : 2.7320152206656796E-5, - "scoreError" : 3.193239556325176E-6, + "score" : 2.719795151933315E-5, + "scoreError" : 3.2049187120831877E-6, "scoreConfidence" : [ - 2.412691265033162E-5, - 3.0513391762981973E-5 + 2.3993032807249964E-5, + 3.0402870231416338E-5 ], "scorePercentiles" : { - "0.0" : 2.633724002001264E-5, - "50.0" : 2.790806473394905E-5, - "90.0" : 2.794377153474337E-5, - "95.0" : 2.794377153474337E-5, - "99.0" : 2.794377153474337E-5, - "99.9" : 2.794377153474337E-5, - "99.99" : 2.794377153474337E-5, - "99.999" : 2.794377153474337E-5, - "99.9999" : 2.794377153474337E-5, - "100.0" : 2.794377153474337E-5 + "0.0" : 2.6562323435674067E-5, + "50.0" : 2.6616486694342435E-5, + "90.0" : 2.8164387632697886E-5, + "95.0" : 2.8164387632697886E-5, + "99.0" : 2.8164387632697886E-5, + "99.9" : 2.8164387632697886E-5, + "99.99" : 2.8164387632697886E-5, + "99.999" : 2.8164387632697886E-5, + "99.9999" : 2.8164387632697886E-5, + "100.0" : 2.8164387632697886E-5 }, "scoreUnit" : "s/op", "rawData" : [ [ - 2.790806473394905E-5, - 2.794377153474337E-5, - 2.792138082742449E-5, - 2.633724002001264E-5, - 2.6490303917154435E-5 + 2.8052458770404443E-5, + 2.8164387632697886E-5, + 2.659410106354693E-5, + 2.6616486694342435E-5, + 2.6562323435674067E-5 ] ] }, @@ -75,32 +75,32 @@ "corpus" : "text" }, "primaryMetric" : { - "score" : 0.194869724, - "scoreError" : 0.0023549891095648906, + "score" : 0.2332505178, + "scoreError" : 0.002148390153575744, "scoreConfidence" : [ - 0.1925147348904351, - 0.19722471310956488 + 0.23110212764642427, + 0.23539890795357574 ], "scorePercentiles" : { - "0.0" : 0.1941997665, - "50.0" : 0.19475896616666666, - "90.0" : 0.1957748385, - "95.0" : 0.1957748385, - "99.0" : 0.1957748385, - "99.9" : 0.1957748385, - "99.99" : 0.1957748385, - "99.999" : 0.1957748385, - "99.9999" : 0.1957748385, - "100.0" : 0.1957748385 + "0.0" : 0.2327619774, + "50.0" : 0.232953819, + "90.0" : 0.234003933, + "95.0" : 0.234003933, + "99.0" : 0.234003933, + "99.9" : 0.234003933, + "99.99" : 0.234003933, + "99.999" : 0.234003933, + "99.9999" : 0.234003933, + "100.0" : 0.234003933 }, "scoreUnit" : "s/op", "rawData" : [ [ - 0.1957748385, - 0.19475896616666666, - 0.19448499083333334, - 0.1941997665, - 0.195130058 + 0.232953819, + 0.234003933, + 0.2328479198, + 0.2327619774, + 0.2336849398 ] ] }, @@ -129,32 +129,32 @@ "corpus" : "model3D" }, "primaryMetric" : { - "score" : 1.5216298784283998E-4, - "scoreError" : 2.6134056259282696E-6, + "score" : 1.6436576357165678E-4, + "scoreError" : 1.2596113460375633E-5, "scoreConfidence" : [ - 1.495495822169117E-4, - 1.5477639346876825E-4 + 1.5176965011128114E-4, + 1.7696187703203242E-4 ], "scorePercentiles" : { - "0.0" : 1.515940239466505E-4, - "50.0" : 1.518362144808743E-4, - "90.0" : 1.5320168433144432E-4, - "95.0" : 1.5320168433144432E-4, - "99.0" : 1.5320168433144432E-4, - "99.9" : 1.5320168433144432E-4, - "99.99" : 1.5320168433144432E-4, - "99.999" : 1.5320168433144432E-4, - "99.9999" : 1.5320168433144432E-4, - "100.0" : 1.5320168433144432E-4 + "0.0" : 1.5934799888481758E-4, + "50.0" : 1.6580862964190983E-4, + "90.0" : 1.669337710280374E-4, + "95.0" : 1.669337710280374E-4, + "99.0" : 1.669337710280374E-4, + "99.9" : 1.669337710280374E-4, + "99.99" : 1.669337710280374E-4, + "99.999" : 1.669337710280374E-4, + "99.9999" : 1.669337710280374E-4, + "100.0" : 1.669337710280374E-4 }, "scoreUnit" : "s/op", "rawData" : [ [ - 1.518362144808743E-4, - 1.5249330899390245E-4, - 1.5320168433144432E-4, - 1.515940239466505E-4, - 1.5168970746132847E-4 + 1.5934799888481758E-4, + 1.6281484453849911E-4, + 1.6692357376502003E-4, + 1.6580862964190983E-4, + 1.669337710280374E-4 ] ] }, @@ -183,32 +183,32 @@ "corpus" : "Rainier.bmp" }, "primaryMetric" : { - "score" : 2.8822180459999998, - "scoreError" : 0.6147377532845272, + "score" : 2.68099617, + "scoreError" : 0.7885563965332603, "scoreConfidence" : [ - 2.2674802927154727, - 3.496955799284527 + 1.8924397734667395, + 3.46955256653326 ], "scorePercentiles" : { - "0.0" : 2.598949862, - "50.0" : 2.943511252, - "90.0" : 2.985083897, - "95.0" : 2.985083897, - "99.0" : 2.985083897, - "99.9" : 2.985083897, - "99.99" : 2.985083897, - "99.999" : 2.985083897, - "99.9999" : 2.985083897, - "100.0" : 2.985083897 + "0.0" : 2.506635972, + "50.0" : 2.585388356, + "90.0" : 2.903237219, + "95.0" : 2.903237219, + "99.0" : 2.903237219, + "99.9" : 2.903237219, + "99.99" : 2.903237219, + "99.999" : 2.903237219, + "99.9999" : 2.903237219, + "100.0" : 2.903237219 }, "scoreUnit" : "s/op", "rawData" : [ [ - 2.598949862, - 2.953478858, - 2.930066361, - 2.943511252, - 2.985083897 + 2.901933504, + 2.903237219, + 2.585388356, + 2.506635972, + 2.507785799 ] ] }, @@ -237,32 +237,32 @@ "corpus" : "Maltese.bmp" }, "primaryMetric" : { - "score" : 1.6395375802, - "scoreError" : 0.05287466499250389, + "score" : 1.650674704, + "scoreError" : 0.035071852261538056, "scoreConfidence" : [ - 1.5866629152074962, - 1.6924122451925039 + 1.615602851738462, + 1.6857465562615381 ], "scorePercentiles" : { - "0.0" : 1.620594794, - "50.0" : 1.635996985, - "90.0" : 1.653876066, - "95.0" : 1.653876066, - "99.0" : 1.653876066, - "99.9" : 1.653876066, - "99.99" : 1.653876066, - "99.999" : 1.653876066, - "99.9999" : 1.653876066, - "100.0" : 1.653876066 + "0.0" : 1.638377177, + "50.0" : 1.655827974, + "90.0" : 1.65843618, + "95.0" : 1.65843618, + "99.0" : 1.65843618, + "99.9" : 1.65843618, + "99.99" : 1.65843618, + "99.999" : 1.65843618, + "99.9999" : 1.65843618, + "100.0" : 1.65843618 }, "scoreUnit" : "s/op", "rawData" : [ [ - 1.653876066, - 1.652097568, - 1.620594794, - 1.635122488, - 1.635996985 + 1.657207507, + 1.65843618, + 1.655827974, + 1.638377177, + 1.643524682 ] ] }, @@ -291,32 +291,32 @@ "corpus" : "Sunrise.bmp" }, "primaryMetric" : { - "score" : 13.942460108199999, - "scoreError" : 2.7906046247424645, + "score" : 12.7290295962, + "scoreError" : 0.5525624445182846, "scoreConfidence" : [ - 11.151855483457535, - 16.733064732942463 + 12.176467151681715, + 13.281592040718285 ], "scorePercentiles" : { - "0.0" : 12.6595252, - "50.0" : 14.215782169, - "90.0" : 14.441000896, - "95.0" : 14.441000896, - "99.0" : 14.441000896, - "99.9" : 14.441000896, - "99.99" : 14.441000896, - "99.999" : 14.441000896, - "99.9999" : 14.441000896, - "100.0" : 14.441000896 + "0.0" : 12.568172428, + "50.0" : 12.823767139, + "90.0" : 12.840710954, + "95.0" : 12.840710954, + "99.0" : 12.840710954, + "99.9" : 12.840710954, + "99.99" : 12.840710954, + "99.999" : 12.840710954, + "99.9999" : 12.840710954, + "100.0" : 12.840710954 }, "scoreUnit" : "s/op", "rawData" : [ [ - 12.6595252, - 14.441000896, - 14.220994907, - 14.174997369, - 14.215782169 + 12.840710954, + 12.836645489, + 12.823767139, + 12.568172428, + 12.575851971 ] ] }, @@ -345,32 +345,32 @@ "corpus" : "compressed_MVT.pbf" }, "primaryMetric" : { - "score" : 0.010820364386623128, - "scoreError" : 0.002525898538605477, + "score" : 0.011504001176764705, + "scoreError" : 0.0021709856642339186, "scoreConfidence" : [ - 0.008294465848017652, - 0.013346262925228605 + 0.009333015512530787, + 0.013674986840998623 ], "scorePercentiles" : { - "0.0" : 0.010376159041237114, - "50.0" : 0.010399470639175257, - "90.0" : 0.011875508952941177, - "95.0" : 0.011875508952941177, - "99.0" : 0.011875508952941177, - "99.9" : 0.011875508952941177, - "99.99" : 0.011875508952941177, - "99.999" : 0.011875508952941177, - "99.9999" : 0.011875508952941177, - "100.0" : 0.011875508952941177 + "0.0" : 0.010519714291666666, + "50.0" : 0.011782424517647059, + "90.0" : 0.011846557505882352, + "95.0" : 0.011846557505882352, + "99.0" : 0.011846557505882352, + "99.9" : 0.011846557505882352, + "99.99" : 0.011846557505882352, + "99.999" : 0.011846557505882352, + "99.9999" : 0.011846557505882352, + "100.0" : 0.011846557505882352 }, "scoreUnit" : "s/op", "rawData" : [ [ - 0.011875508952941177, - 0.011053454846153846, - 0.010399470639175257, - 0.010376159041237114, - 0.010397228453608248 + 0.011846557505882352, + 0.011782424517647059, + 0.011830209235294117, + 0.011541100333333333, + 0.010519714291666666 ] ] }, diff --git a/performance/2026-09-09-dynamic/after-sizes.jsonl b/performance/2026-09-09-dynamic/after-sizes.jsonl index 80e29dd..0967815 100644 --- a/performance/2026-09-09-dynamic/after-sizes.jsonl +++ b/performance/2026-09-09-dynamic/after-sizes.jsonl @@ -1,7 +1,70 @@ -{"corpus":"simpleText","level":9,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":33.087246,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} -{"corpus":"text","level":9,"originalSizeBytes":1232923,"compressedSizeBytes":488094,"singleRunMs":293.477464,"sha256":"39f6f3af429bf689a09a37bb94a1ac4ea5d368251814af5ce5ae54c9e09e8f2f"} -{"corpus":"model3D","level":9,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":2.537058,"sha256":"450f6437d13a19585d0df05da961baf30023451a17612fd84a683a2f2f450ea7"} -{"corpus":"Rainier.bmp","level":9,"originalSizeBytes":6220854,"compressedSizeBytes":3255198,"singleRunMs":4203.219682,"sha256":"e67eda98521873e7a12e80ef1c3e298e342000a7b16a0d297a599a2f3bf7cf80"} -{"corpus":"Maltese.bmp","level":9,"originalSizeBytes":16427390,"compressedSizeBytes":6860004,"singleRunMs":1710.326159,"sha256":"82d5f7e47a65a6f9f9d47068438b5472ec68cd2b6ba1827f93d7dd18a6ce0083"} -{"corpus":"Sunrise.bmp","level":9,"originalSizeBytes":52344054,"compressedSizeBytes":26083978,"singleRunMs":14579.570679,"sha256":"c0bb6198bb9ef637a1cc6bb3007c1ea2b4be493fa772ee4312e47d2fe05ab57c"} -{"corpus":"compressed_MVT.pbf","level":9,"originalSizeBytes":146224,"compressedSizeBytes":91400,"singleRunMs":12.682059,"sha256":"c3f8bcf3e6f73717dc8b242e96b3324b9f0b30dfe2e06fbb8e56f89128c22adb"} +{"corpus":"simpleText","level":0,"originalSizeBytes":100,"compressedSizeBytes":105,"singleRunMs":20.420716,"sha256":"7a4f86cab2c64d7a755ba6244b34b85122a3d7e629073b34930b3d477585100b"} +{"corpus":"simpleText","level":1,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":11.751386,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":2,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.347467,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":3,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.315407,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":4,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.401460,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":5,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.358148,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":6,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.261222,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":7,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.262076,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":8,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.275697,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"simpleText","level":9,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.680594,"sha256":"dfc6c55d533c49b70bb5f358f19c146ad3443a985e6f76144b1ee4e16286e499"} +{"corpus":"text","level":0,"originalSizeBytes":1232923,"compressedSizeBytes":1233018,"singleRunMs":4.814965,"sha256":"cfab8f8c4f21f3b8b8b3cd60a85b7e1243a5aad2a06fa863e9eec73187488605"} +{"corpus":"text","level":1,"originalSizeBytes":1232923,"compressedSizeBytes":599813,"singleRunMs":60.766331,"sha256":"143d81705ac095d278fb6e1fa3932a500916369bc4596da6885cfe2e7d81f756"} +{"corpus":"text","level":2,"originalSizeBytes":1232923,"compressedSizeBytes":581519,"singleRunMs":37.870431,"sha256":"611557ab65d0c35387dfc6121636fd006ff3a237c3a838835f67e31cc79983ce"} +{"corpus":"text","level":3,"originalSizeBytes":1232923,"compressedSizeBytes":565252,"singleRunMs":37.864573,"sha256":"19a3c8ae4b1f0ed21ed27b0e0bb87c22d0ebf7259406f8d748c3d79c3d4888ee"} +{"corpus":"text","level":4,"originalSizeBytes":1232923,"compressedSizeBytes":531466,"singleRunMs":56.182404,"sha256":"d27df2bc4d16b3c9b193b68a7c72cc4208ed4505c2eaafbfc078fbfb29bdd3e1"} +{"corpus":"text","level":5,"originalSizeBytes":1232923,"compressedSizeBytes":521837,"singleRunMs":67.778662,"sha256":"49036c7d2710a45efdf31f3cb63b002ecffe3f8732566b65cd54997e02788bbd"} +{"corpus":"text","level":6,"originalSizeBytes":1232923,"compressedSizeBytes":506455,"singleRunMs":78.658040,"sha256":"3ba0571fcc563672f279cad303810e537dfc18ce61680207dfcd3e2e91abaf67"} +{"corpus":"text","level":7,"originalSizeBytes":1232923,"compressedSizeBytes":506097,"singleRunMs":78.711318,"sha256":"f7b312a37b78362b74cb5c5b1da94aaadec93a4629b19fc3d5cf5300498b993d"} +{"corpus":"text","level":8,"originalSizeBytes":1232923,"compressedSizeBytes":513489,"singleRunMs":83.362418,"sha256":"0008d4cc1d35364514f380a591ec7c01edc292742c5654a50795008ae3b6989c"} +{"corpus":"text","level":9,"originalSizeBytes":1232923,"compressedSizeBytes":488094,"singleRunMs":264.814823,"sha256":"39f6f3af429bf689a09a37bb94a1ac4ea5d368251814af5ce5ae54c9e09e8f2f"} +{"corpus":"model3D","level":0,"originalSizeBytes":2478,"compressedSizeBytes":2483,"singleRunMs":0.058049,"sha256":"7d1354e385451c35f23c9be4ce28245d554943a2219ff0cf3481d5c0a02a4919"} +{"corpus":"model3D","level":1,"originalSizeBytes":2478,"compressedSizeBytes":2169,"singleRunMs":0.198789,"sha256":"cc762b082d3527b26e531d8f8cd04e17467595b5ef1ea32a541b275663e3ef96"} +{"corpus":"model3D","level":2,"originalSizeBytes":2478,"compressedSizeBytes":2168,"singleRunMs":0.153188,"sha256":"7be0094d5c194b33c4337a5c971d25c3ed4e2c3d1d195a75225130310d911733"} +{"corpus":"model3D","level":3,"originalSizeBytes":2478,"compressedSizeBytes":2166,"singleRunMs":0.149645,"sha256":"fa0c3d7374a90b6f9d7f14095e59ecd375b976cd57423d40e18d26332bf768c6"} +{"corpus":"model3D","level":4,"originalSizeBytes":2478,"compressedSizeBytes":2165,"singleRunMs":0.162433,"sha256":"b8bb6e5b0de2dac94d69e676871bd5538d16c6fc909b4a926a9fb42ca33d4846"} +{"corpus":"model3D","level":5,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.162788,"sha256":"4b0cd916546275b9ae57fab7c6d88d94ed1e669669b30c158eb4c06e85e8f0ad"} +{"corpus":"model3D","level":6,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.189867,"sha256":"4b0cd916546275b9ae57fab7c6d88d94ed1e669669b30c158eb4c06e85e8f0ad"} +{"corpus":"model3D","level":7,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.197933,"sha256":"4b0cd916546275b9ae57fab7c6d88d94ed1e669669b30c158eb4c06e85e8f0ad"} +{"corpus":"model3D","level":8,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.121352,"sha256":"4b0cd916546275b9ae57fab7c6d88d94ed1e669669b30c158eb4c06e85e8f0ad"} +{"corpus":"model3D","level":9,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.523221,"sha256":"450f6437d13a19585d0df05da961baf30023451a17612fd84a683a2f2f450ea7"} +{"corpus":"Rainier.bmp","level":0,"originalSizeBytes":6220854,"compressedSizeBytes":6221329,"singleRunMs":4.506621,"sha256":"acf3201e43c503d2705565195eb3bfc176e674b00bc8eeaf55411409398ffb7e"} +{"corpus":"Rainier.bmp","level":1,"originalSizeBytes":6220854,"compressedSizeBytes":3387685,"singleRunMs":128.510272,"sha256":"d86acee038a3272ef53f6be323c941d63ee7fc64544d489d3e81061ba2cb4296"} +{"corpus":"Rainier.bmp","level":2,"originalSizeBytes":6220854,"compressedSizeBytes":3357387,"singleRunMs":113.135627,"sha256":"cb08babeb442d0a7b5ef341c5114d36a9a40c0e9640c848accd37d151af8a3a6"} +{"corpus":"Rainier.bmp","level":3,"originalSizeBytes":6220854,"compressedSizeBytes":3345679,"singleRunMs":108.262991,"sha256":"3c62f22018cd809c25f3c70a9672872a0a0ec916ad89b7eca944c0415093b7dd"} +{"corpus":"Rainier.bmp","level":4,"originalSizeBytes":6220854,"compressedSizeBytes":3325593,"singleRunMs":104.033492,"sha256":"84cf1da1aa0fd2007e5de90ff81e779e616020cf3548affd456350296f12ce6c"} +{"corpus":"Rainier.bmp","level":5,"originalSizeBytes":6220854,"compressedSizeBytes":3313388,"singleRunMs":110.900404,"sha256":"54a7d786396e86dae90937df6dd8425d69557991ec611265a212ad85037e2b63"} +{"corpus":"Rainier.bmp","level":6,"originalSizeBytes":6220854,"compressedSizeBytes":3283450,"singleRunMs":123.108339,"sha256":"fba9e4496d79c376317229a92a905be4351f5487e3db2a91d2287826db2bc7e3"} +{"corpus":"Rainier.bmp","level":7,"originalSizeBytes":6220854,"compressedSizeBytes":3282047,"singleRunMs":126.131032,"sha256":"50d60b742c7b4bfdde3d0a3a6893995cace792bbad1dd85e475e40c4dc2c0221"} +{"corpus":"Rainier.bmp","level":8,"originalSizeBytes":6220854,"compressedSizeBytes":3274905,"singleRunMs":140.425514,"sha256":"d151041825a26ae58bd43d4dc8425663e8587cbfd23a49bf4023dd74d5a414c6"} +{"corpus":"Rainier.bmp","level":9,"originalSizeBytes":6220854,"compressedSizeBytes":3255198,"singleRunMs":4235.598236,"sha256":"e67eda98521873e7a12e80ef1c3e298e342000a7b16a0d297a599a2f3bf7cf80"} +{"corpus":"Maltese.bmp","level":0,"originalSizeBytes":16427390,"compressedSizeBytes":16428645,"singleRunMs":6.525581,"sha256":"d872a98f975735016f16578b716b5c874f98e85abc101426d1142dd3a5c096d6"} +{"corpus":"Maltese.bmp","level":1,"originalSizeBytes":16427390,"compressedSizeBytes":8344362,"singleRunMs":311.848320,"sha256":"fbb73b9022879442d4e1f1ecb02baa6b1ac77119aafde5151b559e0b417dd98c"} +{"corpus":"Maltese.bmp","level":2,"originalSizeBytes":16427390,"compressedSizeBytes":7762283,"singleRunMs":353.512485,"sha256":"382e0863aa03871829f20b35a7d9f69c29108bbfcca7dd1d0097f782be3f8a2b"} +{"corpus":"Maltese.bmp","level":3,"originalSizeBytes":16427390,"compressedSizeBytes":7494606,"singleRunMs":390.544770,"sha256":"387c7f415e7da413a670c5ec9589ef69e744bf442195d53f60996d04c2d661dc"} +{"corpus":"Maltese.bmp","level":4,"originalSizeBytes":16427390,"compressedSizeBytes":7272625,"singleRunMs":361.597747,"sha256":"799d4909f60c7fa4262539af0c182ecf99fae272ed6b031524cf86ff2cef7693"} +{"corpus":"Maltese.bmp","level":5,"originalSizeBytes":16427390,"compressedSizeBytes":7265831,"singleRunMs":466.553285,"sha256":"d62521d1d682ba1afa24845265fcb768883997c5425775d8630b2feaab128464"} +{"corpus":"Maltese.bmp","level":6,"originalSizeBytes":16427390,"compressedSizeBytes":7158472,"singleRunMs":471.089058,"sha256":"cb10f06b36e0eaf03ebf81b8743a321d751979f5e671deb340405dfa6b8986b1"} +{"corpus":"Maltese.bmp","level":7,"originalSizeBytes":16427390,"compressedSizeBytes":7157735,"singleRunMs":476.832862,"sha256":"9ac4463c11aeaac8cc3ca316115118a45d1cec7fc7807cb6da67b58630de2f6b"} +{"corpus":"Maltese.bmp","level":8,"originalSizeBytes":16427390,"compressedSizeBytes":7125327,"singleRunMs":475.871902,"sha256":"a05331809efe04ca4434c5bfd57592571a22c5d30211715d6e24c3828903c640"} +{"corpus":"Maltese.bmp","level":9,"originalSizeBytes":16427390,"compressedSizeBytes":6860004,"singleRunMs":1513.294170,"sha256":"82d5f7e47a65a6f9f9d47068438b5472ec68cd2b6ba1827f93d7dd18a6ce0083"} +{"corpus":"Sunrise.bmp","level":0,"originalSizeBytes":52344054,"compressedSizeBytes":52348049,"singleRunMs":22.612684,"sha256":"4ab78a3e1ba97388ff3dd5e00d9e134bceeb1b5eb3edc7aaf7845c1377fea548"} +{"corpus":"Sunrise.bmp","level":1,"originalSizeBytes":52344054,"compressedSizeBytes":27793016,"singleRunMs":820.017802,"sha256":"7028cd0b1e7d73172e76063b6004aedee371667bca442e8a68ca718f36dac355"} +{"corpus":"Sunrise.bmp","level":2,"originalSizeBytes":52344054,"compressedSizeBytes":27471887,"singleRunMs":1017.839734,"sha256":"38fe2dd9e078be3c88adf86d15cc2da3187ea4c8919a73284f431e68dd9b7392"} +{"corpus":"Sunrise.bmp","level":3,"originalSizeBytes":52344054,"compressedSizeBytes":27404419,"singleRunMs":1229.482338,"sha256":"158c5cb3eb8d7023dc234ec5ae5e4e0d64be93f8c0f2f250bf05da65d5c9aff3"} +{"corpus":"Sunrise.bmp","level":4,"originalSizeBytes":52344054,"compressedSizeBytes":27107867,"singleRunMs":1151.271124,"sha256":"c42c56683342f532ce402a90d066e23d688a19221200648c26ce3b11621cc2e0"} +{"corpus":"Sunrise.bmp","level":5,"originalSizeBytes":52344054,"compressedSizeBytes":27096750,"singleRunMs":1374.580351,"sha256":"734bc825d4f1374115b66c64e1f56edf46c8978185ddaecffd9adc87a2e4c12e"} +{"corpus":"Sunrise.bmp","level":6,"originalSizeBytes":52344054,"compressedSizeBytes":26838825,"singleRunMs":1517.752687,"sha256":"34a1e5b94bf2344b565dc7b11b44f6908bda919a1fea479b2b2e0f557fd26346"} +{"corpus":"Sunrise.bmp","level":7,"originalSizeBytes":52344054,"compressedSizeBytes":26827604,"singleRunMs":1976.267488,"sha256":"cb202e01985166da6621d97ab386edff2eb4274eb8f1237aff36390543dcf18c"} +{"corpus":"Sunrise.bmp","level":8,"originalSizeBytes":52344054,"compressedSizeBytes":26728454,"singleRunMs":1945.606578,"sha256":"7570e8999cbda1a50c9693338f4a11dcf5aed8f6f45ff4cc1def7c3ee945541b"} +{"corpus":"Sunrise.bmp","level":9,"originalSizeBytes":52344054,"compressedSizeBytes":26083978,"singleRunMs":14975.151610,"sha256":"c0bb6198bb9ef637a1cc6bb3007c1ea2b4be493fa772ee4312e47d2fe05ab57c"} +{"corpus":"compressed_MVT.pbf","level":0,"originalSizeBytes":146224,"compressedSizeBytes":146239,"singleRunMs":0.057595,"sha256":"d8239f92d78f0d7fc3e9e9d8557e35365184e7d8c7f432339a8375c422a61c13"} +{"corpus":"compressed_MVT.pbf","level":1,"originalSizeBytes":146224,"compressedSizeBytes":95812,"singleRunMs":2.589306,"sha256":"8e921cc121ff9a262119bd7a2124a36039b95a26a5095349d08ea9b776c0ba34"} +{"corpus":"compressed_MVT.pbf","level":2,"originalSizeBytes":146224,"compressedSizeBytes":94608,"singleRunMs":2.925776,"sha256":"52efa74d70a15df6fa9d67da07da404b7e4628f895f65ddaa94148161762c45c"} +{"corpus":"compressed_MVT.pbf","level":3,"originalSizeBytes":146224,"compressedSizeBytes":94345,"singleRunMs":3.104935,"sha256":"a4090d9493e7e896ce6bc3f1c454e23738aa2e35e5418abb8d98c9f6dafaec94"} +{"corpus":"compressed_MVT.pbf","level":4,"originalSizeBytes":146224,"compressedSizeBytes":93369,"singleRunMs":3.321581,"sha256":"41844dbfb741b35e7e91c17ad039e1439e9601af58a3f70c6a83cac1e5f9491e"} +{"corpus":"compressed_MVT.pbf","level":5,"originalSizeBytes":146224,"compressedSizeBytes":93229,"singleRunMs":3.899664,"sha256":"169dee1b2849bae5fbfcdfd0daaece65729fe589980485d0b441c19050dd97b8"} +{"corpus":"compressed_MVT.pbf","level":6,"originalSizeBytes":146224,"compressedSizeBytes":92605,"singleRunMs":3.968359,"sha256":"87d498941e1d7cae4ee47930a9becc40606244a9e9e4c06d0ef21a3434093459"} +{"corpus":"compressed_MVT.pbf","level":7,"originalSizeBytes":146224,"compressedSizeBytes":92610,"singleRunMs":4.043387,"sha256":"5eb82ecc19fbb18428eceb3e508c2dfdbe4a648bc52733e8db70bd223c732f65"} +{"corpus":"compressed_MVT.pbf","level":8,"originalSizeBytes":146224,"compressedSizeBytes":92631,"singleRunMs":4.437293,"sha256":"00be763dadfed2e2d09467a7da0f564897ddc75421fab3bf3150836470ed0a62"} +{"corpus":"compressed_MVT.pbf","level":9,"originalSizeBytes":146224,"compressedSizeBytes":91400,"singleRunMs":11.638608,"sha256":"c3f8bcf3e6f73717dc8b242e96b3324b9f0b30dfe2e06fbb8e56f89128c22adb"}