perf
This commit is contained in:
parent
024dc42058
commit
61c365dbde
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue