Skip to content

Commit

Permalink
[x/tour] pic: don't make a string copy when writing image
Browse files Browse the repository at this point in the history
Previously, the entire image was encoded into a buffer,
then encoded to a base64 string, which was concatenated
with another string, and written to stdout in one swoop.

We can do this more efficiently by writing the PNG image
to a base64 encoder directly, and using buffered I/O to
batch writes to stdout into moderately-sized chunks.

As an added bonus, though really the main motivation for
doing this optimization now, this helps avoid triggering
the golang/go#38751 issue on the Go Playground.

Switch to the best compression level instead of the default,
reducing encoded image size at the cost of extra computation.
Playground snippets need to be transferred over the network
and kept in storage, so it should be a favorable trade-off.

This CL was based on CL 232177.

For golang/go#38751.

Change-Id: I565fe538aa15910caaff98be156ac64b0d35fff4
Co-authored-by: Alexander Rakoczy <[email protected]>
Reviewed-on: https://go-review.googlesource.com/c/tour/+/232867
Run-TryBot: Dmitri Shuralyov <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Alexander Rakoczy <[email protected]>
X-Tour-Commit: 0608babe047def227de553b6538ed3bd6277acff
  • Loading branch information
dmitshur and toothrot committed May 8, 2020
1 parent 0f95301 commit b6aa4fe
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
16 changes: 10 additions & 6 deletions tour/pic/pic.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
package pic // import "golang.org/x/tour/pic"

import (
"bytes"
"bufio"
"encoding/base64"
"fmt"
"image"
"image/png"
"io"
"os"
)

// Show displays a picture defined by the function f
Expand Down Expand Up @@ -46,11 +47,14 @@ func Show(f func(dx, dy int) [][]uint8) {
// ShowImage displays the image m
// when executed on the Go Playground.
func ShowImage(m image.Image) {
var buf bytes.Buffer
err := png.Encode(&buf, m)
w := bufio.NewWriter(os.Stdout)
defer w.Flush()
io.WriteString(w, "IMAGE:")
b64 := base64.NewEncoder(base64.StdEncoding, w)
err := (&png.Encoder{CompressionLevel: png.BestCompression}).Encode(b64, m)
if err != nil {
panic(err)
}
enc := base64.StdEncoding.EncodeToString(buf.Bytes())
fmt.Println("IMAGE:" + enc)
b64.Close()
io.WriteString(w, "\n")
}
2 changes: 1 addition & 1 deletion tour/pic/pic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ func ExampleShow() {
pic.Show(f)

// Output:
// IMAGE:iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAADKElEQVR4nOzVoRHAMAzAQCfX/VduxjDQk8di+mb+mTlnyKB3vYBc9K4XkIs6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANM6ANO+AAAA//9hKgMPVczXbQAAAABJRU5ErkJggg==
// IMAGE:iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACaUlEQVR42uzVMRGAAAzAwLSHf8tgAAf95QVkyVNvNRN50FWBl10V6ABa0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIB6ADqEAHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdAA6gBZ0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIBSAcgHYB0ANIB6AAq0AFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgHQA0gFIByAdgA6gAh2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADSAUgHIB2AdADyxy8AAP//YSoDD5pLB7MAAAAASUVORK5CYII=
}

0 comments on commit b6aa4fe

Please sign in to comment.