diff --git a/src/zippy/compress.nim b/src/zippy/compress.nim index 0f86880..270464a 100644 --- a/src/zippy/compress.nim +++ b/src/zippy/compress.nim @@ -27,7 +27,7 @@ const ] type - Coin = ref object + Coin = object symbols: seq[uint16] weight: uint64 @@ -38,10 +38,6 @@ template failCompress() = ZippyError, "Unexpected error while compressing" ) -func newCoin(): Coin = - result = Coin() - result.symbols = newSeqOfCap[uint16](maxLitLenCodes) - func `<`(a, b: Coin): bool = a.weight < b.weight func quicksort[T](s: var seq[T], inl, inr: int) = @@ -51,12 +47,12 @@ func quicksort[T](s: var seq[T], inl, inr: int) = let n = r - l + 1 if n < 2: return - let p = s[l + 3 * n div 4] + let p = l + 3 * n div 4 while l <= r: - if s[l] < p: + if s[l] < s[p]: inc l continue - if s[r] > p: + if s[r] > s[p]: dec r continue if l <= r: @@ -108,8 +104,10 @@ func lengthLimitedHuffmanCodeLengths( prevCoins = newSeq[Coin](coins.len) for i in 0 ..< coins.len: - coins[i] = newCoin() - prevCoins[i] = newCoin() + coins[i].symbols.setLen(coins.len) + coins[i].symbols.setLen(0) + prevCoins[i].symbols.setLen(coins.len) + prevCoins[i].symbols.setLen(0) addSymbolCoins(coins, 0) @@ -129,12 +127,10 @@ func lengthLimitedHuffmanCodeLengths( numCoins = 0 for i in countup(0, numCoinsPrev - 2, 2): - let coin = coins[numCoins] - coin.weight = prevCoins[i].weight - coin.symbols.setLen(0) - coin.symbols.add(prevCoins[i].symbols) - coin.symbols.add(prevCoins[i + 1].symbols) - coin.weight += prevCoins[i + 1].weight + coins[numCoins].weight = prevCoins[i].weight + coins[numCoins].symbols.add(prevCoins[i].symbols) + coins[numCoins].symbols.add(prevCoins[i + 1].symbols) + coins[numCoins].weight += prevCoins[i + 1].weight inc numCoins if bitLen < maxBitLen: @@ -144,9 +140,8 @@ func lengthLimitedHuffmanCodeLengths( quicksort(coins, 0, numCoins - 1) for i in 0 ..< numSymbolsUsed - 1: - let coin = coins[i] - for j in 0 ..< coin.symbols.len: - inc depths[coin.symbols[j]] + for j in 0 ..< coins[i].symbols.len: + inc depths[coins[i].symbols[j]] var depthCounts: array[16, uint8] for d in depths: @@ -207,8 +202,8 @@ func compress*(src: seq[uint8]): seq[uint8] = freqLitLen[256] = 1 # Alway 1 end-of-block symbol let - (numCodesLitLen, depthsLitLen, codesLitLen) = lengthLimitedHuffmanCodeLengths(freqLitLen, 257, maxCodeLength) - (numCodesDist, depthsDist, codesDist) = lengthLimitedHuffmanCodeLengths(freqDist, 2, maxCodeLength) + (numCodesLitLen, depthsLitLen, codesLitLen) = lengthLimitedHuffmanCodeLengths(freqLitLen, 257, 10) + (numCodesDist, depthsDist, codesDist) = lengthLimitedHuffmanCodeLengths(freqDist, 2, 6) storedCodesLitLen = min(numCodesLitLen, maxLitLenCodes) storedCodesDist = min(numCodesDist, maxDistCodes) diff --git a/tests/benchmark.nim b/tests/benchmark.nim index 646f6e3..33b0e1b 100644 --- a/tests/benchmark.nim +++ b/tests/benchmark.nim @@ -9,9 +9,18 @@ const "fixed.z" ] golds = [ - "rfctest1.gold", + # "randtest1.gold", + # "randtest2.gold", + # "randtest3.gold", + # "rfctest1.gold", + # "rfctest2.gold", + # "rfctest3.gold", + "tor-list.gold", + # "zerotest1.gold", + # "zerotest2.gold", + # "zerotest3.gold", ] - iterations = 20000 + iterations = 100 # block guzba_zippy_uncompress: # echo "https://github.com/guzba/zippy uncompress" @@ -52,18 +61,18 @@ block guzba_zippy_compress: # let delta = float64(getMonoTime().ticks - start) / 1000000000.0 # echo &" {z}: {delta:.4f}s [{c}]" -# block treeform_miniz_compress: -# echo "https://github.com/treeform/miniz compress" -# for gold in golds: -# let -# uncompressed = readFile(&"tests/data/{gold}") -# start = getMonoTime().ticks -# var c: int -# for i in 0 ..< iterations: -# let compressed = miniz.compress(uncompressed, 1) -# inc(c, compressed.len) -# let delta = float64(getMonoTime().ticks - start) / 1000000000.0 -# echo &" {gold}: {delta:.4f}s [{c}]" +block treeform_miniz_compress: + echo "https://github.com/treeform/miniz compress" + for gold in golds: + let + uncompressed = readFile(&"tests/data/{gold}") + start = getMonoTime().ticks + var c: int + for i in 0 ..< iterations: + let compressed = miniz.compress(uncompressed, 1) + inc(c, compressed.len) + let delta = float64(getMonoTime().ticks - start) / 1000000000.0 + echo &" {gold}: {delta:.4f}s [{c}]" # block nimlang_zip_uncompress: # Requires zlib1.dll # echo "https://github.com/nim-lang/zip uncompress" diff --git a/tests/test.nim b/tests/test.nim index 0819037..1439fda 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -33,12 +33,12 @@ const # gold = readFile(&"tests/data/{golds[i]}") # assert uncompress(z) == gold -# block all_symbols: -# var data: seq[uint8] -# for i in 0.uint8 .. high(uint8): -# data.add(i) -# let compressed = compress(data) -# assert data == uncompress(compressed) +block all_symbols: + var data: seq[uint8] + for i in 0.uint8 .. high(uint8): + data.add(i) + let compressed = compress(data) + assert data == uncompress(compressed) for gold in golds: let