Skip to content

Use pool of ObjectTraverseStacks in ToObject().#2386

Merged
lahma merged 1 commit into
sebastienros:mainfrom
StringEpsilon:ToObjectOptimization
Apr 7, 2026
Merged

Use pool of ObjectTraverseStacks in ToObject().#2386
lahma merged 1 commit into
sebastienros:mainfrom
StringEpsilon:ToObjectOptimization

Conversation

@StringEpsilon

Copy link
Copy Markdown
Contributor

For some workloads, ObjectInstance.ToObject() causes the Stack<object> internal to ObjectTraverseStack to allocate additional memory, which is then promptly disposed of, only to be re-allocated again on the next call that requires the conversion.

Using a pool reduces the amount of allocation and, for the workload I am optimizing for, makes ToObject() so fast that it vanishes from the profiler.

@StringEpsilon

StringEpsilon commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Benchmark:

[MemoryDiagnoser]
public class ToObjectBench
{
    private Engine _engine = new Engine().SetValue("test", new Dictionary<int, object>());

    [Benchmark]
    public void InteropCall() =>
        _engine.Execute("""
            for(var i = 0; i < 10; i++) {
                test.Add(i, {});
            }
            test.Clear();
            """);
}
Method Mean Error StdDev Gen0 Gen1 Allocated
main 6.500 us 0.0278 us 0.0247 us 1.3657 0.0229 22.35 KB
branch 6.142 us 0.0468 us 0.0415 us 1.0757 0.0153 17.66 KB

I also ran the interop benchmark set, but they showed no difference in runtime with only one test showing a very small decrease in allocated memory.

@lahma

lahma commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator

I think ObjectPool is not thread-safe so it shouldn't be exposed as static field (static via ownership), Engine field would be safe. Needs rebase.

For some workloads, ToObject causes the Stack<object> internal to ObjectTraverseStack to allocate additional memory, which is then prompty disposed of only to be re-allocated again on the next call that requires the conversion.

Using a pool reduces the amount of allocation and, for the workload I am optimizing for, makes `ToObject()` so fast that it vanishes from the profiler.or the workload I am optimizing for, makes ToObject() so fast that it vanishes from the profiler.
@StringEpsilon StringEpsilon force-pushed the ToObjectOptimization branch from 4fdf4b1 to dccd0a9 Compare April 7, 2026 19:08

@lahma lahma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you!

@lahma lahma merged commit d4d231b into sebastienros:main Apr 7, 2026
4 checks passed
@StringEpsilon StringEpsilon deleted the ToObjectOptimization branch April 7, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants