Skip to content

Commit

Permalink
0.3.4, inflate faster
Browse files Browse the repository at this point in the history
  • Loading branch information
guzba committed Nov 14, 2020
1 parent 4ccf8f0 commit c82fd96
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ Each file is uncompressed 1000 times:
**https://github.com/guzba/zippy** results:
File | Time
--- | ---:
alice29.txt | 0.9395s
urls.10K | 3.9862s
rfctest3.gold | 0.2052s
alice29.txt | 0.7797s
urls.10K | 3.5913s
rfctest3.gold | 0.1774s
randtest3.gold | 0.0373s
paper-100k.pdf | 0.6453s
geo.protodata | 0.2535s
geo.protodata | 0.2516s

https://github.com/nim-lang/zip results: (Requires zlib1.dll)
File | Time
Expand Down
52 changes: 34 additions & 18 deletions src/zippy/inflate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ func inflateBlock(b: var BitStream, dst: var seq[uint8], fixedCodes: bool) =
literalHuffman = initHuffman(unpacked[0 ..< hlit], maxLitLenCodes)
distanceHuffman = initHuffman(unpacked[hlit ..< unpacked.len], maxDistCodes)

var pos = dst.len
var op = dst.len
while true:
let symbol = decodeSymbol(b, literalHuffman)
if symbol <= 255:
if pos >= dst.len:
dst.setLen((pos + 1) * 2)
dst[pos] = symbol.uint8
inc pos
if op >= dst.len:
dst.setLen((op + 1) * 2)
dst[op] = symbol.uint8
inc op
elif symbol == 256:
break
else:
Expand All @@ -218,22 +218,38 @@ func inflateBlock(b: var BitStream, dst: var seq[uint8], fixedCodes: bool) =
b.readBits(baseDistanceExtraBits[distIndex])
).int

if totalDist > pos:
if totalDist > op:
failUncompress()

if pos + totalLength > dst.len:
dst.setLen((pos + totalLength) * 2)

var remaining = totalLength
while totalDist >= 8 and remaining >= 8:
copy64(dst, dst, pos, pos - totalDist)
inc(pos, 8)
dec(remaining, 8)
for i in 0 ..< remaining:
dst[pos + i] = dst[pos - totalDist + i]
inc(pos, remaining)
# Min match is 3 so leave room to overwrite by 13
if op + totalLength + 13 > dst.len:
dst.setLen((op + totalLength) * 2 + 10)

if totalLength <= 16 and totalDist >= 8 and dst.len > op + 16:
copy64(dst, dst, op, op - totalDist)
copy64(dst, dst, op + 8, op - totalDist + 8)
inc(op, totalLength)
elif dst.len - op >= totalLength + 10:
var
src = op - totalDist
pos = op
remaining = totalLength
while pos - src < 8:
copy64(dst, dst, pos, src)
dec(remaining, pos - src)
inc(pos, pos - src)
while remaining > 0:
copy64(dst, dst, pos, src)
inc(src, 8)
inc(pos, 8)
dec(remaining, 8)
inc(op, totalLength)
else:
for i in op ..< op + totalLength:
dst[op] = dst[op - totalDist]
inc op

dst.setLen(pos)
dst.setLen(op)

func inflateNoCompression(b: var BitStream, dst: var seq[uint8]) =
b.skipRemainingBitsInCurrentByte()
Expand Down
2 changes: 1 addition & 1 deletion zippy.nimble
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
packageName = "zippy"
version = "0.3.3"
version = "0.3.4"
author = "Ryan Oldenburg"
description = "In-progress pure Nim implementation of deflate and zlib."
license = "MIT"
Expand Down

0 comments on commit c82fd96

Please sign in to comment.