aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Gusted <williamzijl7@hotmail.com> 2023-11-12 16:36:57 +0100
committerGravatar GitHub <noreply@github.com> 2023-11-12 16:36:57 +0100
commit1834cecd7e1ad98a4affda5ce6fbc4ae01995de7 (patch)
tree75b53766e1732bf68cd8134158eea83c0ca38b28
parentFix spelling mistake (diff)
downloadfasthttp-1834cecd7e1ad98a4affda5ce6fbc4ae01995de7.tar.gz
fasthttp-1834cecd7e1ad98a4affda5ce6fbc4ae01995de7.tar.bz2
fasthttp-1834cecd7e1ad98a4affda5ce6fbc4ae01995de7.zip
Lazy load stackless functions (#1656)
- I noticed that fasthttp was taking up 1.8MB of heap memory, even though it wasn't being used. This turned out to be the stackless function: 1.80MB github.com/valyala/fasthttp/stackless.NewFunc - Lazy load the stackless functions with sync.Once, given this a simple atomic read, it shouldn't affect performance for the fast-path (I haven't seen benchmarks with compression enabled).
-rw-r--r--brotli.go12
-rw-r--r--compress.go24
-rw-r--r--stackless/writer.go13
3 files changed, 45 insertions, 4 deletions
diff --git a/brotli.go b/brotli.go
index c829c39..032bd95 100644
--- a/brotli.go
+++ b/brotli.go
@@ -132,7 +132,17 @@ func WriteBrotliLevel(w io.Writer, p []byte, level int) (int, error) {
}
}
-var stacklessWriteBrotli = stackless.NewFunc(nonblockingWriteBrotli)
+var (
+ stacklessWriteBrotliOnce sync.Once
+ stacklessWriteBrotliFunc func(ctx interface{}) bool
+)
+
+func stacklessWriteBrotli(ctx interface{}) {
+ stacklessWriteBrotliOnce.Do(func() {
+ stacklessWriteBrotliFunc = stackless.NewFunc(nonblockingWriteBrotli)
+ })
+ stacklessWriteBrotliFunc(ctx)
+}
func nonblockingWriteBrotli(ctxv interface{}) {
ctx := ctxv.(*compressCtx)
diff --git a/compress.go b/compress.go
index 8494d56..1f44f1e 100644
--- a/compress.go
+++ b/compress.go
@@ -177,7 +177,17 @@ func WriteGzipLevel(w io.Writer, p []byte, level int) (int, error) {
}
}
-var stacklessWriteGzip = stackless.NewFunc(nonblockingWriteGzip)
+var (
+ stacklessWriteGzipOnce sync.Once
+ stacklessWriteGzipFunc func(ctx interface{}) bool
+)
+
+func stacklessWriteGzip(ctx interface{}) {
+ stacklessWriteGzipOnce.Do(func() {
+ stacklessWriteGzipFunc = stackless.NewFunc(nonblockingWriteGzip)
+ })
+ stacklessWriteGzipFunc(ctx)
+}
func nonblockingWriteGzip(ctxv interface{}) {
ctx := ctxv.(*compressCtx)
@@ -270,7 +280,17 @@ func WriteDeflateLevel(w io.Writer, p []byte, level int) (int, error) {
}
}
-var stacklessWriteDeflate = stackless.NewFunc(nonblockingWriteDeflate)
+var (
+ stacklessWriteDeflateOnce sync.Once
+ stacklessWriteDeflateFunc func(ctx interface{}) bool
+)
+
+func stacklessWriteDeflate(ctx interface{}) {
+ stacklessWriteDeflateOnce.Do(func() {
+ stacklessWriteDeflateFunc = stackless.NewFunc(nonblockingWriteDeflate)
+ })
+ stacklessWriteDeflateFunc(ctx)
+}
func nonblockingWriteDeflate(ctxv interface{}) {
ctx := ctxv.(*compressCtx)
diff --git a/stackless/writer.go b/stackless/writer.go
index b0d3e8d..347e464 100644
--- a/stackless/writer.go
+++ b/stackless/writer.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
+ "sync"
"github.com/valyala/bytebufferpool"
)
@@ -98,7 +99,17 @@ func (w *writer) do(op op) error {
var errHighLoad = errors.New("cannot compress data due to high load")
-var stacklessWriterFunc = NewFunc(writerFunc)
+var (
+ stacklessWriterFuncOnce sync.Once
+ stacklessWriterFuncFunc func(ctx interface{}) bool
+)
+
+func stacklessWriterFunc(ctx interface{}) bool {
+ stacklessWriterFuncOnce.Do(func() {
+ stacklessWriterFuncFunc = NewFunc(writerFunc)
+ })
+ return stacklessWriterFuncFunc(ctx)
+}
func writerFunc(ctx interface{}) {
w := ctx.(*writer)