zapjournald/encoder.go
Evgenii Stratonikov d6ea4d0bbf [#12] Use buffer pool for message encoding
```
goos: linux
goarch: amd64
pkg: git.frostfs.info/TrueCloudLab/zapjournald
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
                                     │      1       │                  2                  │
                                     │    sec/op    │   sec/op     vs base                │
Logger/standard/no_fields-8             450.3n ± 2%   452.9n ± 3%        ~ (p=0.138 n=10)
Logger/standard/application_fields-8    610.4n ± 1%   608.4n ± 1%        ~ (p=0.325 n=10)
Logger/standard/journald_fields-8       595.8n ± 5%   604.5n ± 1%        ~ (p=0.075 n=10)
Logger/journald/no_fields-8            1809.0n ± 4%   900.4n ± 1%  -50.23% (p=0.000 n=10)
Logger/journald/application_fields-8    2.037µ ± 5%   1.087µ ± 1%  -46.62% (p=0.000 n=10)
Logger/journald/journald_fields-8       2.054µ ± 4%   1.119µ ± 1%  -45.52% (p=0.000 n=10)
geomean                                 1.036µ        753.1n       -27.33%

                                     │        1        │                  2                   │
                                     │      B/op       │    B/op     vs base                  │
Logger/standard/no_fields-8               0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Logger/standard/application_fields-8      128.0 ± 0%     128.0 ± 0%        ~ (p=1.000 n=10) ¹
Logger/standard/journald_fields-8         64.00 ± 0%     64.00 ± 0%        ~ (p=1.000 n=10) ¹
Logger/journald/no_fields-8            1206.000 ± 0%     5.000 ± 0%  -99.59% (p=0.000 n=10)
Logger/journald/application_fields-8     1494.0 ± 0%     133.0 ± 0%  -91.10% (p=0.000 n=10)
Logger/journald/journald_fields-8       1478.00 ± 0%     85.00 ± 0%  -94.25% (p=0.000 n=10)
geomean                                              ²               -83.36%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                     │       1       │                  2                   │
                                     │   allocs/op   │ allocs/op   vs base                  │
Logger/standard/no_fields-8             0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Logger/standard/application_fields-8    1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
Logger/standard/journald_fields-8       1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
Logger/journald/no_fields-8            29.000 ± 0%     1.000 ± 0%  -96.55% (p=0.000 n=10)
Logger/journald/application_fields-8   30.000 ± 0%     2.000 ± 0%  -93.33% (p=0.000 n=10)
Logger/journald/journald_fields-8      31.000 ± 0%     3.000 ± 0%  -90.32% (p=0.000 n=10)
geomean                                            ²               -75.38%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean
```

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2023-10-18 11:30:00 +03:00

58 lines
1.4 KiB
Go

package zapjournald
import (
"bytes"
"strings"
"go.uber.org/zap/buffer"
)
var pool = buffer.NewPool()
func writeFieldBytes(buf *buffer.Buffer, name string, value []byte) {
buf.Write([]byte(name))
if bytes.ContainsRune(value, '\n') {
// According to the format, if the value includes a newline
// need to write the field name, plus a newline, then the
// size (64bit LE), the field data and a final newline.
buf.Write([]byte{'\n'})
appendUint64Binary(buf, uint64(len(value)))
} else {
buf.Write([]byte{'='})
}
buf.Write(value)
buf.Write([]byte{'\n'})
}
func writeField(buf *buffer.Buffer, name string, value string) {
buf.Write([]byte(name))
if strings.ContainsRune(value, '\n') {
// According to the format, if the value includes a newline
// need to write the field name, plus a newline, then the
// size (64bit LE), the field data and a final newline.
buf.Write([]byte{'\n'})
// 1 allocation here.
// binary.Write(w, binary.LittleEndian, uint64(len(value)))
appendUint64Binary(buf, uint64(len(value)))
} else {
buf.Write([]byte{'='})
}
buf.WriteString(value)
buf.Write([]byte{'\n'})
}
func appendUint64Binary(buf *buffer.Buffer, v uint64) {
// Copied from https://github.com/golang/go/blob/go1.21.3/src/encoding/binary/binary.go#L119
buf.Write([]byte{
byte(v),
byte(v >> 8),
byte(v >> 16),
byte(v >> 24),
byte(v >> 32),
byte(v >> 40),
byte(v >> 48),
byte(v >> 56),
})
}