Skip to content

Commit 1a4bbae

Browse files
authored
Merge pull request #225 from klauspost/add-cli-benchmark
Add CLI benchmarks
2 parents 6945807 + eb139b7 commit 1a4bbae

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

cmd/lz4c/compress.go

+42
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package main
22

33
import (
4+
"bytes"
45
"flag"
56
"fmt"
67
"io"
78
"os"
9+
"runtime"
810
"sync/atomic"
11+
"time"
912

1013
"code.cloudfoundry.org/bytefmt"
1114
"github.com/schollz/progressbar/v3"
@@ -26,6 +29,7 @@ func Compress(fs *flag.FlagSet) cmdflag.Handler {
2629
fs.UintVar(&level, "l", 0, "compression level (0=fastest)")
2730
var concurrency int
2831
fs.IntVar(&concurrency, "c", -1, "concurrency (default=all CPUs")
32+
bench := fs.Int("bench", 0, "Run benchmark n times. No output will be written")
2933

3034
var lvl lz4.CompressionLevel
3135
switch level {
@@ -87,6 +91,33 @@ func Compress(fs *flag.FlagSet) cmdflag.Handler {
8791
if err != nil {
8892
return fidx, err
8993
}
94+
if *bench > 0 {
95+
fmt.Print("Reading ", filename, "...")
96+
input, err := io.ReadAll(file)
97+
if err != nil {
98+
return fidx, err
99+
}
100+
file.Close()
101+
for i := 0; i < *bench; i++ {
102+
fmt.Print("\nCompressing...")
103+
runtime.GC()
104+
start := time.Now()
105+
counter := wCounter{out: io.Discard}
106+
zw.Reset(&counter)
107+
_, err := io.Copy(zw, bytes.NewReader(input))
108+
if err != nil {
109+
return fidx, err
110+
}
111+
output := counter.n
112+
elapsed := time.Since(start)
113+
ms := elapsed.Round(time.Millisecond)
114+
mbPerSec := (float64(len(input)) / 1e6) / (float64(elapsed) / (float64(time.Second)))
115+
pct := float64(output) * 100 / float64(len(input))
116+
fmt.Printf(" %d -> %d [%.02f%%]; %v, %.01fMB/s", len(input), output, pct, ms, mbPerSec)
117+
}
118+
fmt.Println("")
119+
continue
120+
}
90121
finfo, err := file.Stat()
91122
if err != nil {
92123
return fidx, err
@@ -147,3 +178,14 @@ func Compress(fs *flag.FlagSet) cmdflag.Handler {
147178
return len(args), nil
148179
}
149180
}
181+
182+
type wCounter struct {
183+
n int
184+
out io.Writer
185+
}
186+
187+
func (w *wCounter) Write(p []byte) (n int, err error) {
188+
n, err = w.out.Write(p)
189+
w.n += n
190+
return n, err
191+
}

cmd/lz4c/uncompress.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package main
22

33
import (
4+
"bytes"
45
"flag"
56
"fmt"
67
"io"
78
"os"
9+
"runtime"
810
"strings"
11+
"time"
912

1013
"github.com/schollz/progressbar/v3"
1114

@@ -14,7 +17,8 @@ import (
1417
)
1518

1619
// Uncompress uncompresses a set of files or from stdin to stdout.
17-
func Uncompress(_ *flag.FlagSet) cmdflag.Handler {
20+
func Uncompress(fs *flag.FlagSet) cmdflag.Handler {
21+
bench := fs.Int("bench", 0, "Run benchmark n times. No output will be written")
1822
return func(args ...string) (int, error) {
1923
zr := lz4.NewReader(nil)
2024

@@ -31,6 +35,32 @@ func Uncompress(_ *flag.FlagSet) cmdflag.Handler {
3135
if err != nil {
3236
return fidx, err
3337
}
38+
39+
if *bench > 0 {
40+
fmt.Print("Reading ", zfilename, "...")
41+
compressed, err := io.ReadAll(zfile)
42+
if err != nil {
43+
return fidx, err
44+
}
45+
zfile.Close()
46+
for i := 0; i < *bench; i++ {
47+
fmt.Print("\nDecompressing...")
48+
runtime.GC()
49+
start := time.Now()
50+
zr.Reset(bytes.NewReader(compressed))
51+
output, err := io.Copy(io.Discard, zr)
52+
if err != nil {
53+
return fidx, err
54+
}
55+
elapsed := time.Since(start)
56+
ms := elapsed.Round(time.Millisecond)
57+
mbPerSec := (float64(output) / 1e6) / (float64(elapsed) / (float64(time.Second)))
58+
pct := float64(output) * 100 / float64(len(compressed))
59+
fmt.Printf(" %d -> %d [%.02f%%]; %v, %.01fMB/s", len(compressed), output, pct, ms, mbPerSec)
60+
}
61+
fmt.Println("")
62+
continue
63+
}
3464
zinfo, err := zfile.Stat()
3565
if err != nil {
3666
return fidx, err

0 commit comments

Comments
 (0)