This commit is contained in:
Ryan Oldenburg 2020-11-02 15:34:26 -06:00
parent 024dc42058
commit 61c365dbde
3 changed files with 45 additions and 41 deletions

View File

@ -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)

View File

@ -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"

View File

@ -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