Merge branch 'vegz' into 'master'

[gzep] Add simple sync.Pool task.

See merge request slon/shad-go-private!72
This commit is contained in:
verytable 2022-05-05 19:19:39 +00:00
commit 0cbe3d86c0
4 changed files with 111 additions and 0 deletions

View file

@ -1,3 +1,12 @@
- group: Analysis
start: 05-05-2022 18:00
deadline: 15-05-2022 23:59
tasks:
- task: testifycheck
score: 200
- task: gzep
score: 100
- group: Bonus
start: 14-04-2022 17:59
deadline: 22-05-2022 23:59

21
gzep/README.md Normal file
View file

@ -0,0 +1,21 @@
## gzep [runtime]
В этой задаче нужно победить бенчмарк, "улучшив" функцию сериализации в `gzip`.
Пример запуска бенчмарка для бейзлайна и авторского решения:
```
goos: linux
goarch: amd64
pkg: gitlab.com/slon/shad-go/gzep
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
BenchmarkEncodeSimple
BenchmarkEncodeSimple-8 8307 124841 ns/op 813872 B/op 17 allocs/op
BenchmarkEncode
BenchmarkEncode-8 2094512 620.0 ns/op 0 B/op 0 allocs/op
PASS
ok gitlab.com/slon/shad-go/gzep 3.756s
```
### С чего начать?
Запустите бенчмарк локально. Найдите в коде `compress/gzip` откуда берутся эти 800 килобайт на операцию?

17
gzep/encode.go Normal file
View file

@ -0,0 +1,17 @@
//go:build !solution
package gzep
import (
"compress/gzip"
"io"
)
func Encode(data []byte, w io.Writer) error {
ww := gzip.NewWriter(w)
defer func() { _ = ww.Close() }()
if _, err := ww.Write(data); err != nil {
return err
}
return ww.Flush()
}

64
gzep/encode_test.go Normal file
View file

@ -0,0 +1,64 @@
package gzep
import (
"bytes"
"compress/gzip"
"io"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/slon/shad-go/tools/testtool"
)
func BenchmarkEncode(b *testing.B) {
data := []byte(
"New function should generally only return pointer types, " +
"since a pointer can be put into the return interface " +
"value without an allocation. " +
testtool.RandomName(),
)
b.ResetTimer()
b.ReportAllocs()
for n := 0; n < b.N; n++ {
require.NoError(b, Encode(data, io.Discard))
}
}
func TestRoundTrip(t *testing.T) {
testCases := []struct {
name string
in string
}{
{name: "empty", in: ""},
{name: "simple", in: "A long time ago in a galaxy far, far away..."},
{name: "random", in: testtool.RandomName()},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
buf := new(bytes.Buffer)
require.NoError(t, Encode([]byte(tc.in), buf))
out, err := decode(buf.Bytes())
require.NoError(t, err, tc.in)
require.Equal(t, tc.in, string(out))
})
}
}
func decode(data []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
if _, err := io.Copy(buf, r); err != nil {
return nil, err
}
return buf.Bytes(), nil
}