Skip to content

Commit

Permalink
Lazy load stackless functions (#1656)
Browse files Browse the repository at this point in the history
- 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).
  • Loading branch information
Gusted committed Nov 12, 2023
1 parent 3267649 commit 1834cec
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
12 changes: 11 additions & 1 deletion brotli.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
24 changes: 22 additions & 2 deletions compress.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion stackless/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
"sync"

"github.com/valyala/bytebufferpool"
)
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 1834cec

Please sign in to comment.