From 0378e329849cf663ec0459c5ac68cf28727f38ac Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Thu, 24 Jun 2021 14:06:05 -0700 Subject: [PATCH] Unsafe cast to string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid the allocation of converting the byte slice or buffer contents to a string with an unsafe cast. This should be safe because the CheckedEntry is invalidated once ce.Write is called, so it's not expected to use the associated string again. ``` name old time/op new time/op delta Writer/single-4 422ns ±21% 329ns ± 2% -21.99% (p=0.000 n=10+10) Writer/splits-4 433ns ± 4% 384ns ± 5% -11.26% (p=0.000 n=9+9) name old alloc/op new alloc/op delta Writer/single-4 16.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) Writer/splits-4 16.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Writer/single-4 2.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) Writer/splits-4 2.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) ``` --- zapio/writer.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zapio/writer.go b/zapio/writer.go index 29699c86d..8b2911564 100644 --- a/zapio/writer.go +++ b/zapio/writer.go @@ -23,6 +23,7 @@ package zapio import ( "bytes" "io" + "unsafe" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -114,7 +115,10 @@ func (w *Writer) flush(allowEmpty bool) { } func (w *Writer) log(b []byte) { - if ce := w.Log.Check(w.Level, string(b)); ce != nil { + // This is unsafe, but the contract is that a CheckedEntry is no longer + // valid once we call ce.Write, so it promises not to reuse this + // string. + if ce := w.Log.Check(w.Level, *(*string)(unsafe.Pointer(&b))); ce != nil { ce.Write() } }