Snappy
Posted on
Jun 15, 2018
Snappy
是 Google
开发的压缩和解压缩的库,最初使用 C++
编写,后来又造了一个 golang
版本的轮子。由于目前该压缩算法还没有放到 go
的标准库中去,所以需要通过 go get -u github.com/golang/snappy
安装。
与其他常见的压缩算法相比,Snappy
存在的目的并不是为了获得最大程度的压缩比,正如其名字所言,它旨在保持合理的压缩比的同时最大限度地提高压缩和解压缩的速度。
Snappy
对数据处理速度上做了很大的优化,但它并不是没有缺点,相对于其他算法来说,Snappy
压缩得到的文件体积会更大一点。如果你更在意压缩速度而不是压缩比的话,Snappy
可能会是一个很好的选择。
compression 下面,我们对比一下 Snappy
压缩算法和其他两种常见的压缩算法( zlib
和 gzip
)的性能。首先,我们定一个 Compressor
接口,并使 Zlib
,Gzip
和 Snappy
这三个结构体均实现它。
1 2 3 4 5 6 7 type Zlib struct {}type Gzip struct {}type Snappy struct {}type Compressor interface { Compress(io.Writer, io.Reader) error }
zlib 1 2 3 4 5 6 7 8 9 10 11 12 13 func (_ *Zlib) Compress (w io.Writer, r io.Reader) error { zw, err := zlib.NewWriterLevel(w, zlib.BestSpeed) if err != nil { return err } defer zw.Close() _, err = io.Copy(zw, r) if err != nil { return err } return nil }
gzip 1 2 3 4 5 6 7 8 9 10 11 12 13 func (_ *Gzip) Compress (w io.Writer, r io.Reader) error { gw, err := gzip.NewWriterLevel(w, gzip.BestSpeed) if err != nil { return err } defer gw.Close() _, err = io.Copy(gw, r) if err != nil { return err } return nil }
snappy 1 2 3 4 5 6 7 8 9 10 func (_ *Snappy) compress (w io.Writer, r io.Reader) error { sw := snappy.NewBufferedWriter(w) defer sw.Close() _, err := io.Copy(sw, r) if err != nil { return err } return nil }
对于压缩的性能,可以从压缩比和压缩时间这两点进行衡量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 func main () { f, err := os.Open("somebigfile" ) if err != nil { log.Fatal(err) } fGzip, _ := os.Create("gzip" ) fZlib, _ := os.Create("zlib" ) fSnappy, _ := os.Create("snappy" ) cs := map [compressor]io.Writer{ &Gzip{}: fGzip, &Zlib{}: fZlib, &Snappy{}: fSnappy, } for c, v := range cs { t := time.Now() err := c.compress(v, f) if err != nil { fmt.Println(err) } d := time.Since(t) fmt.Printf("method: %s, time spend: %.02f, ratio: %.05f%%\n" , v.Name(), d.Seconds(), compressionRatio(f, v)) f.Seek(0 , 0 ) } }
1 2 3 4 5 6 7 func compressionRatio (f1, f2 *os.File) float64 { f1s, _ := f1.Stat() f1size := f1s.Size() f2s, _ := f2.Stat() f2size := f2s.Size() return float64 (f2size) / float64 (f1size) * 100 }
Snappy
在速度上来说比 zlib
和 gzip
快得多,但文件相对要大 20%
到 100%
。在 64
位模式的 Core i7
处理器上,Snappy
可以达到 250~500
兆每秒的压缩速度,可以说是非常惊人了。
1 2 3 4 $ go run main.go method: gzip, time spend: 8.38s, ratio: 7.576% method: zlib, time spend: 9.13s, ratio: 7.576% method: snappy, time spend: 1.96s, ratio: 18.813%
相比其他的压缩库,Snappy
能在保持特定的压缩率下拥有惊人的压缩速度,压缩普通文本文件的速度是其他库的 1.5-1.7
倍,HTML能达到 2-4
倍,但是对于 JPEG
、PNG
以及其他的已压缩的数据,压缩速度不会有明显改善。