Skip to content

feat: add optional caching of params and constants#25

Merged
hsluoyz merged 1 commit intoapache:masterfrom
pboyd04:CachingOfParamsAndConstants
Sep 4, 2025
Merged

feat: add optional caching of params and constants#25
hsluoyz merged 1 commit intoapache:masterfrom
pboyd04:CachingOfParamsAndConstants

Conversation

@pboyd04
Copy link
Copy Markdown
Contributor

@pboyd04 pboyd04 commented Sep 4, 2025

If you have a bunch of govaluate expressions kept in memory with similar parameters and/or similar constants this allows you to turn on a cache with a build tag (assuming you have golang 1.24 or greater). This reduces the amount of memory the expressions consume by sharing stages across expressions.

Benchmarks without cache:

BenchmarkSingleParse-24                          4112127               289.5 ns/op           224 B/op          6 allocs/op
BenchmarkSimpleParse-24                           709797              1628 ns/op            1211 B/op         29 allocs/op
BenchmarkFullParse-24                             209383              6999 ns/op            4687 B/op        116 allocs/op
BenchmarkEvaluationSingle-24                    128901000                8.998 ns/op           0 B/op          0 allocs/op
BenchmarkEvaluationNumericLiteral-24            43751962                25.94 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationLiteralModifiers-24          17263702                71.93 ns/op            8 B/op          1 allocs/op
BenchmarkEvaluationParameter-24                 76307056                16.52 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationParameters-24                37903912                35.15 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationParametersModifiers-24       10787078                99.12 ns/op           16 B/op          2 allocs/op
BenchmarkComplexExpression-24                   71083309                17.57 ns/op            0 B/op          0 allocs/op
BenchmarkRegexExpression-24                      1591404               762.6 ns/op          1428 B/op         18 allocs/op
BenchmarkConstantRegexExpression-24              8835997               187.5 ns/op             0 B/op          0 allocs/op
BenchmarkAccessors-24                           14347064                75.44 ns/op            8 B/op          1 allocs/op
BenchmarkAccessorMethod-24                       3005412               407.0 ns/op           168 B/op          7 allocs/op
BenchmarkAccessorMethodParams-24                 2729622               464.5 ns/op           208 B/op          8 allocs/op
BenchmarkNestedAccessors-24                     11189446               100.7 ns/op             0 B/op          0 allocs/op

Benchmarks with cache:

BenchmarkSingleParse-24                          4696720               259.4 ns/op           120 B/op          4 allocs/op
BenchmarkSimpleParse-24                           744771              1548 ns/op             794 B/op         21 allocs/op
BenchmarkFullParse-24                             220964              7149 ns/op            3226 B/op         88 allocs/op
BenchmarkEvaluationSingle-24                    100000000               10.97 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationNumericLiteral-24            31738222                38.02 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationLiteralModifiers-24          13775227                85.30 ns/op            8 B/op          1 allocs/op
BenchmarkEvaluationParameter-24                 41696491                28.30 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationParameters-24                22658908                53.23 ns/op            0 B/op          0 allocs/op
BenchmarkEvaluationParametersModifiers-24       10979146               108.7 ns/op            16 B/op          2 allocs/op
BenchmarkComplexExpression-24                   52387562                22.92 ns/op            0 B/op          0 allocs/op
BenchmarkRegexExpression-24                      1585320               757.0 ns/op          1431 B/op         18 allocs/op
BenchmarkConstantRegexExpression-24              5570799               212.2 ns/op             0 B/op          0 allocs/op
BenchmarkAccessors-24                           14245064                83.62 ns/op            8 B/op          1 allocs/op
BenchmarkAccessorMethod-24                       2444245               483.7 ns/op           168 B/op          7 allocs/op
BenchmarkAccessorMethodParams-24                 2501234               485.1 ns/op           208 B/op          8 allocs/op
BenchmarkNestedAccessors-24                     10499632               114.6 ns/op             0 B/op          0 allocs/op

@hsluoyz hsluoyz requested a review from Copilot September 4, 2025 15:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces optional caching of evaluation stages for parameters and constants to reduce memory usage when multiple govaluate expressions share similar values. The caching is enabled through a build tag and requires Go 1.24+ to leverage weak pointers.

  • Refactored stage planning to use cached stages for parameters and constants
  • Implemented build-tag conditional caching using weak references to avoid memory leaks
  • Added defensive copying to prevent mutation of shared cached stages

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
stagePlanner.go Modified to use new caching functions and added defensive copying for shared stages
noCache.go Fallback implementation that maintains original behavior without caching
cache.go Cache implementation using weak pointers and sync.Map for Go 1.24+

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread cache.go
@@ -0,0 +1,75 @@
//go:build go1.24 && cache
Copy link

Copilot AI Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build constraint 'go1.24' may not work as expected. Go build tags typically use version formats like 'go1.24.0' or semantic versioning. Consider using a more standard build tag format.

Suggested change
//go:build go1.24 && cache
//go:build go1.24.0 && cache

Copilot uses AI. Check for mistakes.
Comment thread noCache.go
@@ -0,0 +1,18 @@
//go:build !go1.24 || !cache
Copy link

Copilot AI Sep 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build constraint '!go1.24' should match the format used in cache.go. If cache.go uses 'go1.24', this constraint should be '!go1.24', but consider using a more standard build tag format consistently.

Suggested change
//go:build !go1.24 || !cache
//go:build !(go1.24 && cache)

Copilot uses AI. Check for mistakes.
@hsluoyz hsluoyz merged commit 564541f into apache:master Sep 4, 2025
8 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 4, 2025

🎉 This PR is included in version 1.10.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants