diff --git a/kflate/src/commonMain/kotlin/com/rafambn/kflate/util/BitUtils.kt b/kflate/src/commonMain/kotlin/com/rafambn/kflate/util/BitUtils.kt index 31c3739..55d22c7 100644 --- a/kflate/src/commonMain/kotlin/com/rafambn/kflate/util/BitUtils.kt +++ b/kflate/src/commonMain/kotlin/com/rafambn/kflate/util/BitUtils.kt @@ -134,7 +134,7 @@ internal fun writeBlock( val (codeLengthTree, maxCodeLengthBits) = buildHuffmanTreeFromFrequencies(codeLengthFrequencies, 7) val numCodeLengthCodes = countCodeLengthCodes(codeLengthTree) - val fixedBlockLength = (blockLength + 5) shl 3 + val storedBlockLength = storedBlockBitLength(blockLength, bitPosition) val fixedTypedLength = calculateCodeLength(literalFrequencies, FIXED_LENGTH_TREE) + calculateCodeLength(distanceFrequencies, FIXED_DISTANCE_TREE) + extraBits val dynamicTypedLength = calculateCodeLength(literalFrequencies, dynamicLiteralTree) + @@ -142,7 +142,7 @@ internal fun writeBlock( calculateCodeLength(codeLengthFrequencies, codeLengthTree) + 2 * codeLengthFrequencies[16] + 3 * codeLengthFrequencies[17] + 7 * codeLengthFrequencies[18] - if (shouldUseStoredBlock(blockStart, fixedBlockLength, fixedTypedLength, dynamicTypedLength)) { + if (shouldUseStoredBlock(blockStart, storedBlockLength, fixedTypedLength, dynamicTypedLength)) { return writeFixedBlock(output, currentBitPosition, data.sliceArray(blockStart until blockStart + blockLength)) } @@ -268,3 +268,17 @@ internal fun shouldUseStoredBlock( ): Boolean { return blockStart >= 0 && storedLength <= fixedLength && storedLength <= dynamicLength } + +/** + * Returns the stored block cost after the three bit block header. + * + * The header itself is present in every block type, while a stored block adds + * padding before its four byte length header. Keeping the common header out of + * this value lets it be compared directly with the fixed and dynamic token + * costs. + */ +internal fun storedBlockBitLength(blockLength: Int, bitPosition: Long): Int { + val headerEnd = bitPosition + 3L + val padding = ((8L - (headerEnd and 7L)) and 7L).toInt() + return (blockLength shl 3) + 32 + padding +} diff --git a/kflate/src/jvmTest/kotlin/InternalHelpersCoverageTest.kt b/kflate/src/jvmTest/kotlin/InternalHelpersCoverageTest.kt index ecee2ae..08779b6 100644 --- a/kflate/src/jvmTest/kotlin/InternalHelpersCoverageTest.kt +++ b/kflate/src/jvmTest/kotlin/InternalHelpersCoverageTest.kt @@ -1,5 +1,6 @@ package com.rafambn.kflate +import com.rafambn.kflate.algorithm.inflate import com.rafambn.kflate.compression.Gzip as CompressionGzip import com.rafambn.kflate.decompression.Gzip as DecompressionGzip import com.rafambn.kflate.error.FlateError @@ -29,9 +30,11 @@ import com.rafambn.kflate.util.readFourBytesBE import com.rafambn.kflate.util.readTwoBytes import com.rafambn.kflate.util.shiftToNextByte import com.rafambn.kflate.util.shouldUseStoredBlock +import com.rafambn.kflate.util.storedBlockBitLength import com.rafambn.kflate.util.toIsoStringBytes import com.rafambn.kflate.util.writeBits import com.rafambn.kflate.util.writeBits16 +import com.rafambn.kflate.util.writeBlock import com.rafambn.kflate.util.writeBytes import com.rafambn.kflate.util.writeBytesBE import kotlin.test.Test @@ -84,6 +87,91 @@ class InternalHelpersCoverageTest { assertTrue(!shouldUseStoredBlock(-1, 1, 1, 1)) assertTrue(!shouldUseStoredBlock(0, 2, 1, 2)) assertTrue(!shouldUseStoredBlock(0, 2, 2, 1)) + assertEquals(117, storedBlockBitLength(10, 0)) + assertEquals(112, storedBlockBitLength(10, 5)) + assertEquals(119, storedBlockBitLength(10, 6)) + assertTrue(shouldUseStoredBlock(0, storedBlockBitLength(10, 6), 119, 119)) + } + + @Test + fun blockWriterAccountsForStoredBlockAlignment() { + val data = ByteArray(26) { (230 + it).toByte() } + val symbols = IntArray(data.size) { 230 + it } + val literalFrequencies = IntArray(288) + for (symbol in symbols) { + literalFrequencies[symbol]++ + } + + val output = ByteArray(256) + writeBlock( + data = data, + output = output, + isFinal = true, + symbols = symbols, + literalFrequencies = literalFrequencies, + distanceFrequencies = IntArray(32), + extraBits = 0, + symbolCount = symbols.size, + blockStart = 0, + blockLength = data.size, + bitPosition = 5, + ) + + val blockType = (output[0].toInt() ushr 5) and 7 + assertEquals(1, blockType, "block type=$blockType") + } + + @Test + fun blockWriterPreservesWholeStreamStoredBlockSavings() { + val prefix = byteArrayOf(253.toByte(), 254.toByte(), 255.toByte()) + val payload = ByteArray(26) { (230 + it).toByte() } + val data = prefix + payload + val prefixSymbols = intArrayOf(253, 254, 255) + val payloadSymbols = IntArray(payload.size) { 230 + it } + + val prefixLiteralFrequencies = IntArray(288) + for (symbol in prefixSymbols) { + prefixLiteralFrequencies[symbol]++ + } + val payloadLiteralFrequencies = IntArray(288) + for (symbol in payloadSymbols) { + payloadLiteralFrequencies[symbol]++ + } + + val output = ByteArray(128) + val prefixEndBitPosition = writeBlock( + data = data, + output = output, + isFinal = false, + symbols = prefixSymbols, + literalFrequencies = prefixLiteralFrequencies, + distanceFrequencies = IntArray(32), + extraBits = 0, + symbolCount = prefixSymbols.size, + blockStart = 0, + blockLength = prefix.size, + bitPosition = 0, + ) + assertEquals(37L, prefixEndBitPosition) + + val finalEndBitPosition = writeBlock( + data = data, + output = output, + isFinal = true, + symbols = payloadSymbols, + literalFrequencies = payloadLiteralFrequencies, + distanceFrequencies = IntArray(32), + extraBits = 0, + symbolCount = payloadSymbols.size, + blockStart = prefix.size, + blockLength = payload.size, + bitPosition = prefixEndBitPosition, + ) + assertEquals(280L, finalEndBitPosition) + + val compressed = output.copyOf(shiftToNextByte(finalEndBitPosition)) + assertEquals(35, compressed.size) + assertContentEquals(data, inflate(compressed, InflateState(validationMode = 2))) } @Test diff --git a/performance/2026-09-09-stored/RESULTS.md b/performance/2026-09-09-stored/RESULTS.md new file mode 100644 index 0000000..512970e --- /dev/null +++ b/performance/2026-09-09-stored/RESULTS.md @@ -0,0 +1,60 @@ +# Choose stored blocks using their actual padding cost + +Use the current bit position when comparing stored, fixed and dynamic blocks. This corrects near-tie decisions at non-byte-aligned boundaries. + +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 | +| ---: | ---: | ---: | ---: | +| 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 | 37,251,418 | 0.0000% | + +### 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 | +| --- | ---: | ---: | ---: | ---: | +| simpleText | 84 | 84 | 0.0000% | 84 | +| text | 492,523 | 492,523 | 0.0000% | 503,400 | +| model3D | 2,153 | 2,153 | 0.0000% | 2,149 | +| Rainier.bmp | 3,258,570 | 3,258,570 | 0.0000% | 3,270,382 | +| Maltese.bmp | 7,034,092 | 7,034,092 | 0.0000% | 7,090,887 | +| Sunrise.bmp | 26,372,269 | 26,372,269 | 0.0000% | 26,652,810 | +| compressed_MVT.pbf | 91,727 | 91,727 | 0.0000% | 91,400 | + +## Boundary case + +The regression test writes a complete RAW stream with three high-byte literals in a nonfinal fixed block, followed by 26 high-byte literals. The first block ends at bit 37. The old cost estimate chooses a final fixed block ending at bit 281, requiring 36 bytes. Accounting for padding selects a stored block ending at bit 280, requiring 35 bytes. This saves one byte in this specific case; the seven corpus files at all ten levels retain identical sizes. + +## Validation + +Linux JVM tests and the 70-case size sweep validate correctness. The whole-stream regression verifies all 29 decoded bytes using strict KFlate validation. No throughput improvement is claimed. + +Reproduce with `./gradlew :kflate:jvmTest`; the regression is `InternalHelpersCoverageTest.blockWriterPreservesWholeStreamStoredBlockSavings`. `RatioSweep.java` contains the corpus sweep and JDK interoperability checks. Measurements ran before committing the same implementation with this report. diff --git a/performance/2026-09-09-stored/RatioSweep.java b/performance/2026-09-09-stored/RatioSweep.java new file mode 100644 index 0000000..996a4ce --- /dev/null +++ b/performance/2026-09-09-stored/RatioSweep.java @@ -0,0 +1,37 @@ +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.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}%n", name, level, input.length, output.length, ms); + } + } + } +} diff --git a/performance/2026-09-09-stored/after-sizes.jsonl b/performance/2026-09-09-stored/after-sizes.jsonl new file mode 100644 index 0000000..4109c70 --- /dev/null +++ b/performance/2026-09-09-stored/after-sizes.jsonl @@ -0,0 +1,70 @@ +{"corpus":"simpleText","level":0,"originalSizeBytes":100,"compressedSizeBytes":105,"singleRunMs":17.743099} +{"corpus":"simpleText","level":1,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":9.717891} +{"corpus":"simpleText","level":2,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.338182} +{"corpus":"simpleText","level":3,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.307948} +{"corpus":"simpleText","level":4,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.272352} +{"corpus":"simpleText","level":5,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.224498} +{"corpus":"simpleText","level":6,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.267385} +{"corpus":"simpleText","level":7,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.202015} +{"corpus":"simpleText","level":8,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.198751} +{"corpus":"simpleText","level":9,"originalSizeBytes":100,"compressedSizeBytes":84,"singleRunMs":0.478129} +{"corpus":"text","level":0,"originalSizeBytes":1232923,"compressedSizeBytes":1233018,"singleRunMs":4.361065} +{"corpus":"text","level":1,"originalSizeBytes":1232923,"compressedSizeBytes":599813,"singleRunMs":52.279190} +{"corpus":"text","level":2,"originalSizeBytes":1232923,"compressedSizeBytes":581519,"singleRunMs":36.646794} +{"corpus":"text","level":3,"originalSizeBytes":1232923,"compressedSizeBytes":565252,"singleRunMs":36.735742} +{"corpus":"text","level":4,"originalSizeBytes":1232923,"compressedSizeBytes":531466,"singleRunMs":65.162215} +{"corpus":"text","level":5,"originalSizeBytes":1232923,"compressedSizeBytes":521837,"singleRunMs":63.198932} +{"corpus":"text","level":6,"originalSizeBytes":1232923,"compressedSizeBytes":506455,"singleRunMs":74.787364} +{"corpus":"text","level":7,"originalSizeBytes":1232923,"compressedSizeBytes":506097,"singleRunMs":76.796766} +{"corpus":"text","level":8,"originalSizeBytes":1232923,"compressedSizeBytes":513489,"singleRunMs":81.337974} +{"corpus":"text","level":9,"originalSizeBytes":1232923,"compressedSizeBytes":492523,"singleRunMs":220.988788} +{"corpus":"model3D","level":0,"originalSizeBytes":2478,"compressedSizeBytes":2483,"singleRunMs":0.043470} +{"corpus":"model3D","level":1,"originalSizeBytes":2478,"compressedSizeBytes":2169,"singleRunMs":0.261532} +{"corpus":"model3D","level":2,"originalSizeBytes":2478,"compressedSizeBytes":2168,"singleRunMs":0.149276} +{"corpus":"model3D","level":3,"originalSizeBytes":2478,"compressedSizeBytes":2166,"singleRunMs":0.138922} +{"corpus":"model3D","level":4,"originalSizeBytes":2478,"compressedSizeBytes":2165,"singleRunMs":0.127254} +{"corpus":"model3D","level":5,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.614859} +{"corpus":"model3D","level":6,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.203552} +{"corpus":"model3D","level":7,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.282327} +{"corpus":"model3D","level":8,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.254732} +{"corpus":"model3D","level":9,"originalSizeBytes":2478,"compressedSizeBytes":2153,"singleRunMs":0.446036} +{"corpus":"Rainier.bmp","level":0,"originalSizeBytes":6220854,"compressedSizeBytes":6221329,"singleRunMs":6.567415} +{"corpus":"Rainier.bmp","level":1,"originalSizeBytes":6220854,"compressedSizeBytes":3387685,"singleRunMs":109.501732} +{"corpus":"Rainier.bmp","level":2,"originalSizeBytes":6220854,"compressedSizeBytes":3357387,"singleRunMs":99.991340} +{"corpus":"Rainier.bmp","level":3,"originalSizeBytes":6220854,"compressedSizeBytes":3345679,"singleRunMs":98.796737} +{"corpus":"Rainier.bmp","level":4,"originalSizeBytes":6220854,"compressedSizeBytes":3325593,"singleRunMs":102.281264} +{"corpus":"Rainier.bmp","level":5,"originalSizeBytes":6220854,"compressedSizeBytes":3313388,"singleRunMs":109.360161} +{"corpus":"Rainier.bmp","level":6,"originalSizeBytes":6220854,"compressedSizeBytes":3283450,"singleRunMs":120.609099} +{"corpus":"Rainier.bmp","level":7,"originalSizeBytes":6220854,"compressedSizeBytes":3282047,"singleRunMs":125.539764} +{"corpus":"Rainier.bmp","level":8,"originalSizeBytes":6220854,"compressedSizeBytes":3274905,"singleRunMs":140.489890} +{"corpus":"Rainier.bmp","level":9,"originalSizeBytes":6220854,"compressedSizeBytes":3258570,"singleRunMs":4123.953838} +{"corpus":"Maltese.bmp","level":0,"originalSizeBytes":16427390,"compressedSizeBytes":16428645,"singleRunMs":6.887125} +{"corpus":"Maltese.bmp","level":1,"originalSizeBytes":16427390,"compressedSizeBytes":8344362,"singleRunMs":304.151030} +{"corpus":"Maltese.bmp","level":2,"originalSizeBytes":16427390,"compressedSizeBytes":7762283,"singleRunMs":351.255122} +{"corpus":"Maltese.bmp","level":3,"originalSizeBytes":16427390,"compressedSizeBytes":7494606,"singleRunMs":389.044940} +{"corpus":"Maltese.bmp","level":4,"originalSizeBytes":16427390,"compressedSizeBytes":7272625,"singleRunMs":405.927534} +{"corpus":"Maltese.bmp","level":5,"originalSizeBytes":16427390,"compressedSizeBytes":7265831,"singleRunMs":521.798475} +{"corpus":"Maltese.bmp","level":6,"originalSizeBytes":16427390,"compressedSizeBytes":7158472,"singleRunMs":529.408796} +{"corpus":"Maltese.bmp","level":7,"originalSizeBytes":16427390,"compressedSizeBytes":7157735,"singleRunMs":534.236659} +{"corpus":"Maltese.bmp","level":8,"originalSizeBytes":16427390,"compressedSizeBytes":7125327,"singleRunMs":537.898069} +{"corpus":"Maltese.bmp","level":9,"originalSizeBytes":16427390,"compressedSizeBytes":7034092,"singleRunMs":1486.123488} +{"corpus":"Sunrise.bmp","level":0,"originalSizeBytes":52344054,"compressedSizeBytes":52348049,"singleRunMs":32.460883} +{"corpus":"Sunrise.bmp","level":1,"originalSizeBytes":52344054,"compressedSizeBytes":27793016,"singleRunMs":929.263105} +{"corpus":"Sunrise.bmp","level":2,"originalSizeBytes":52344054,"compressedSizeBytes":27471887,"singleRunMs":1111.007610} +{"corpus":"Sunrise.bmp","level":3,"originalSizeBytes":52344054,"compressedSizeBytes":27404419,"singleRunMs":1207.959139} +{"corpus":"Sunrise.bmp","level":4,"originalSizeBytes":52344054,"compressedSizeBytes":27107867,"singleRunMs":1293.493213} +{"corpus":"Sunrise.bmp","level":5,"originalSizeBytes":52344054,"compressedSizeBytes":27096750,"singleRunMs":1539.210897} +{"corpus":"Sunrise.bmp","level":6,"originalSizeBytes":52344054,"compressedSizeBytes":26838825,"singleRunMs":1699.000512} +{"corpus":"Sunrise.bmp","level":7,"originalSizeBytes":52344054,"compressedSizeBytes":26827604,"singleRunMs":1941.963146} +{"corpus":"Sunrise.bmp","level":8,"originalSizeBytes":52344054,"compressedSizeBytes":26728454,"singleRunMs":2157.738874} +{"corpus":"Sunrise.bmp","level":9,"originalSizeBytes":52344054,"compressedSizeBytes":26372269,"singleRunMs":14320.729426} +{"corpus":"compressed_MVT.pbf","level":0,"originalSizeBytes":146224,"compressedSizeBytes":146239,"singleRunMs":0.056534} +{"corpus":"compressed_MVT.pbf","level":1,"originalSizeBytes":146224,"compressedSizeBytes":95812,"singleRunMs":2.755843} +{"corpus":"compressed_MVT.pbf","level":2,"originalSizeBytes":146224,"compressedSizeBytes":94608,"singleRunMs":3.234385} +{"corpus":"compressed_MVT.pbf","level":3,"originalSizeBytes":146224,"compressedSizeBytes":94345,"singleRunMs":3.484409} +{"corpus":"compressed_MVT.pbf","level":4,"originalSizeBytes":146224,"compressedSizeBytes":93369,"singleRunMs":3.746026} +{"corpus":"compressed_MVT.pbf","level":5,"originalSizeBytes":146224,"compressedSizeBytes":93229,"singleRunMs":4.607743} +{"corpus":"compressed_MVT.pbf","level":6,"originalSizeBytes":146224,"compressedSizeBytes":92605,"singleRunMs":4.673451} +{"corpus":"compressed_MVT.pbf","level":7,"originalSizeBytes":146224,"compressedSizeBytes":92610,"singleRunMs":4.873132} +{"corpus":"compressed_MVT.pbf","level":8,"originalSizeBytes":146224,"compressedSizeBytes":92631,"singleRunMs":5.248747} +{"corpus":"compressed_MVT.pbf","level":9,"originalSizeBytes":146224,"compressedSizeBytes":91727,"singleRunMs":10.274067} diff --git a/performance/2026-09-09-stored/before-sizes.jsonl b/performance/2026-09-09-stored/before-sizes.jsonl new file mode 100644 index 0000000..6b0a261 --- /dev/null +++ b/performance/2026-09-09-stored/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-stored/source-sha256.json b/performance/2026-09-09-stored/source-sha256.json new file mode 100644 index 0000000..6a93549 --- /dev/null +++ b/performance/2026-09-09-stored/source-sha256.json @@ -0,0 +1,3 @@ +{ + "kflate/src/commonMain/kotlin/com/rafambn/kflate/util/BitUtils.kt": "8c418ea809645e7a3d60289b55cd3856eea521916b3cb35ff7424fcb68ba745a" +}