From ff3e2edbc31996c4f1c30dc867769c6cfa566d7d Mon Sep 17 00:00:00 2001 From: Kyle Xiao Date: Thu, 22 Aug 2024 13:11:37 +0400 Subject: [PATCH] perf(mcache): no alloc (#227) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit goos: darwin goarch: arm64 pkg: github.com/bytedance/gopkg/lang/mcache │ ./old.out │ ./new.out │ │ sec/op │ sec/op vs base │ MCache4096-12 26.270n ± 2% 9.533n ± 1% -63.71% (p=0.002 n=6) MCache10M-12 25.885n ± 2% 9.486n ± 0% -63.36% (p=0.002 n=6) MCache4096Parallel-12 105.3µ ± 17% 113.4µ ± 7% ~ (p=0.065 n=6) MCache10MParallel-12 123.7µ ± 5% 120.8µ ± 17% ~ (p=0.310 n=6) geomean 1.725µ 1.055µ -38.83% │ ./old.out │ ./new.out │ │ B/op │ B/op vs base │ MCache4096-12 24.00 ± 0% 0.00 ± 0% -100.00% (p=0.002 n=6) MCache10M-12 27.50 ± 5% 0.00 ± 0% -100.00% (p=0.002 n=6) MCache4096Parallel-12 234.7Ki ± 23% 0.0Ki ± 0% -100.00% (p=0.002 n=6) MCache10MParallel-12 804424.50 ± 3% 74.50 ± ? -99.99% (p=0.002 n=6) geomean 3.282Ki ? ¹ ² ¹ summaries must be >0 to compute geomean ² ratios must be >0 to compute geomean │ ./old.out │ ./new.out │ │ allocs/op │ allocs/op vs base │ MCache4096-12 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.002 n=6) MCache10M-12 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.002 n=6) MCache4096Parallel-12 10.00k ± 23% 0.00k ± 0% -100.00% (p=0.002 n=6) MCache10MParallel-12 32.48k ± 4% 0.00k ± 0% -100.00% (p=0.002 n=6) geomean 134.3 ? ¹ ² ¹ summaries must be >0 to compute geomean ² ratios must be >0 to compute geomean --- lang/mcache/mcache.go | 24 +++++++++++++++++++----- lang/mcache/utils.go | 2 +- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lang/mcache/mcache.go b/lang/mcache/mcache.go index 1e07472f..8fea275d 100644 --- a/lang/mcache/mcache.go +++ b/lang/mcache/mcache.go @@ -16,6 +16,7 @@ package mcache import ( "sync" + "unsafe" "github.com/bytedance/gopkg/lang/dirtmake" ) @@ -25,12 +26,19 @@ const maxSize = 46 // index contains []byte which cap is 1< 0 && capacity[0] > size { c = capacity[0] } - var ret = caches[calcIndex(c)].Get().([]byte) - ret = ret[:size] + + i := calcIndex(c) + + ret := []byte{} + h := (*bytesHeader)(unsafe.Pointer(&ret)) + h.Len = size + h.Cap = 1 << i + h.Data = caches[i].Get().(*byte) return ret } @@ -68,6 +82,6 @@ func Free(buf []byte) { if !isPowerOfTwo(size) { return } - buf = buf[:0] - caches[bsr(size)].Put(buf) + h := (*bytesHeader)(unsafe.Pointer(&buf)) + caches[bsr(size)].Put(h.Data) } diff --git a/lang/mcache/utils.go b/lang/mcache/utils.go index 71326f92..dd8698ae 100644 --- a/lang/mcache/utils.go +++ b/lang/mcache/utils.go @@ -21,5 +21,5 @@ func bsr(x int) int { } func isPowerOfTwo(x int) bool { - return (x & (-x)) == x + return (x != 0) && ((x & (-x)) == x) }