mpb
mpb copied to clipboard
Invalid rate calculation
Here is a modified version of this example, to use a ProxyWriter. It does not show the right rate:
package main
import (
"io"
"time"
"github.com/vbauerster/mpb/v8"
"github.com/vbauerster/mpb/v8/decor"
)
func main() {
var total int64 = 1024 * 1024 * 500
p := mpb.New(
mpb.WithWidth(60),
mpb.WithRefreshRate(180*time.Millisecond),
)
bar := p.New(total,
mpb.BarStyle().Rbound("|"),
mpb.PrependDecorators(
decor.Counters(decor.SizeB1000(0), "% .2f / % .2f"),
),
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_GO, 30),
decor.Name(" ] "),
decor.EwmaSpeed(decor.SizeB1024(0), "% .2f", 30),
),
)
bar.SetTotal(total, false)
bar.EnableTriggerComplete()
var data [64 * 1024]byte
pw := bar.ProxyWriter(io.Discard)
for i := 0; i < 1024; i++ {
pw.Write(data[:])
time.Sleep(time.Second / 10)
}
pw.Close()
p.Wait()
}
As you can see, this is doing 64KiB of writes every tenth of a second, so that means the speed here is 640KiB/s. Right?
Running this command consistently shows me a rate output of somewhere between 60 and 90 GiB/s. What?
Implementation of Ewma prefixed decorators is delegated to ewma lib. So if you decided to use it I kindly recommend to read its documentation thoroughly. If you need a quick fix I recommend to use decor.AverageSpeed instead. In your example you use ProxyWriter(io.Discard) so you could end up measuring write speed of io.Discard. By using ProxyReader instead I've got adequate results with decor.EwmaSpeed. Try io example with following patch:
diff --git a/_examples/io/main.go b/_examples/io/main.go
index 252a967..eeae8d9 100644
--- a/_examples/io/main.go
+++ b/_examples/io/main.go
@@ -11,8 +11,20 @@ import (
)
func main() {
- var total int64 = 1024 * 1024 * 500
- reader := io.LimitReader(rand.Reader, total)
+ var total int64 = 64 * 1024 * 1024
+
+ r, w := io.Pipe()
+
+ go func() {
+ for i := 0; i < 1024; i++ {
+ _, err := io.Copy(w, io.LimitReader(rand.Reader, 64*1024))
+ if err != nil {
+ panic(err)
+ }
+ time.Sleep(time.Second / 10)
+ }
+ w.Close()
+ }()
p := mpb.New(
mpb.WithWidth(60),
@@ -27,12 +39,12 @@ func main() {
mpb.AppendDecorators(
decor.EwmaETA(decor.ET_STYLE_GO, 30),
decor.Name(" ] "),
- decor.EwmaSpeed(decor.SizeB1024(0), "% .2f", 30),
+ decor.EwmaSpeed(decor.SizeB1024(0), "% .2f", 60),
),
)
// create proxy reader
- proxyReader := bar.ProxyReader(reader)
+ proxyReader := bar.ProxyReader(r)
defer proxyReader.Close()
// copy from proxyReader, ignoring errors
Hmm, I'm surprised that whether you use ProxyReader or ProxyWriter makes a difference - does this mean that the Proxy measurements are starting and also stopping clocks that only run during the Read or Write call? How might I reliably obtain the overall io.Copy speed, considering that either the Reader or Writer might be slow?