From ebe678443fcff7735e4d926e918256b5e33b7ad1 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sun, 8 Nov 2020 20:21:04 -0600 Subject: [PATCH] faster compress, ~5% --- src/zippy.nim | 4 ++-- src/zippy/common.nim | 3 +++ src/zippy/deflate.nim | 13 +++++++++---- tests/benchmark.nim | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/zippy.nim b/src/zippy.nim index f6865a2..fbc507e 100644 --- a/src/zippy.nim +++ b/src/zippy.nim @@ -114,11 +114,11 @@ func uncompress( inflate(src[pos ..< ^8], dst) - let checksum = cast[ptr uint32](src[src.len - 8].unsafeAddr)[] + let checksum = read32(src[src.len - 8].unsafeAddr) if checksum != crc32(dst): raise newException(ZippyError, "Checksum verification failed") - let isize = cast[ptr uint32](src[src.len - 4].unsafeAddr)[] + let isize = read32(src[src.len - 4].unsafeAddr) if isize != dst.len.uint32: raise newException(ZippyError, "Size verification failed") of dfZlib: diff --git a/src/zippy/common.nim b/src/zippy/common.nim index 0d74ad5..f5473a4 100644 --- a/src/zippy/common.nim +++ b/src/zippy/common.nim @@ -101,6 +101,9 @@ const when defined(release): {.push checks: off.} +template read32*(p: pointer): uint32 = + cast[ptr uint32](p)[] + func adler32*(data: seq[uint8]): uint32 = ## See https://github.com/madler/zlib/blob/master/adler32.c diff --git a/src/zippy/deflate.nim b/src/zippy/deflate.nim index 902c864..4ca8fa7 100644 --- a/src/zippy/deflate.nim +++ b/src/zippy/deflate.nim @@ -284,10 +284,15 @@ func lz77Encode(src: seq[uint8]): (seq[uint16], seq[int], seq[int], int) = prevOffset = offset var matchLen: int - for i in 0 ..< stop - pos: - if src[pos - offset + i] != src[pos + i]: - break - inc matchLen + if ( + (read32(src[pos - offset].unsafeAddr) xor read32(src[pos].unsafeAddr) + ) shl 8) == 0: + # The first 3 bytes match (the hash of them got us here so usually do) + inc(matchLen, 3) + for i in 3 ..< stop - pos: + if src[pos - offset + i] != src[pos + i]: + break + inc matchLen if matchLen > longestMatchLen: longestMatchLen = matchLen diff --git a/tests/benchmark.nim b/tests/benchmark.nim index 8f38a70..89bc5c0 100644 --- a/tests/benchmark.nim +++ b/tests/benchmark.nim @@ -1,4 +1,5 @@ -import miniz, nimPNG/nimz, std/monotimes, strformat, zip/zlib, zippy +import std/monotimes, strformat, zip/zlib, zippy +# import miniz, nimPNG/nimz, const zs = [