Skip to content

Conversation

@h3xds1nz
Copy link
Member

@h3xds1nz h3xds1nz commented Jul 14, 2024

Description

Replaces boxing Stack with Stack<bool>, increasing overall performance and decreasing allocations/code-size.
Also replaces non-generic Stack with Stack<BamlNodeInfo> and makes it readonly.

For ilustration, here are some benchmarks:

1 boxing stack vs. generic

Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
BoxingStack 67.83 ns 1.107 ns 0.981 ns 0.0238 869 B 400 B
GenericStack 22.23 ns 0.213 ns 0.189 ns 0.0038 210 B 64 B
Benchmark code
[Benchmark]
public void BoxingStack()
{
    Stack stack = new Stack();
    stack.Push(true);

    int i = 0;
    while (i < 10)
    {
        if ((bool)stack.Peek())
        {
            stack.Pop();
            stack.Push(true);
        }
        i++;
    }


}
[Benchmark]
public void GenericStack()
{
    Stack<bool> stack = new Stack<bool>();
    stack.Push(true);

    int i = 0;
    while (i < 10)
    {
        if (stack.Peek())
        {
            stack.Pop();
            stack.Push(true);
        }
        i++;
    }

3 boxing stacks vs. generic

Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
BoxingStack 207.90 ns 3.092 ns 2.582 ns 0.0715 1,798 B 1200 B
GenericStack 59.11 ns 0.923 ns 0.863 ns 0.0114 441 B 192 B
Benchmark code
[Benchmark]
public void BoxingStack()
{
    Stack stack = new Stack();
    stack.Push(true);
    Stack stack2 = new Stack();
    stack2.Push(true);
    Stack stack3 = new Stack();
    stack3.Push(true);

    int i = 0;
    while (i < 10)
    {
        if ((bool)stack.Peek())
        {
            stack.Pop();
            stack.Push(true);
        }
        if ((bool)stack2.Peek())
        {
            stack2.Pop();
            stack2.Push(true);
        }
        if ((bool)stack3.Peek())
        {
            stack3.Pop();
            stack3.Push(true);
        }
        i++;
    }


}
[Benchmark]
public void GenericStack()
{
    Stack<bool> stack = new Stack<bool>();
    stack.Push(true);
    Stack<bool> stack2 = new Stack<bool>();
    stack2.Push(true);
    Stack<bool> stack3 = new Stack<bool>();
    stack3.Push(true);

    int i = 0;
    while (i < 10)
    {
        if (stack.Peek())
        {
            stack.Pop();
            stack.Push(true);
        }
        if (stack2.Peek())
        {
            stack2.Pop();
            stack2.Push(true);
        }
        if (stack3.Peek())
        {
            stack3.Pop();
            stack3.Push(true);
        }
        i++;
    }

Customer Impact

Increased performance, decreased allocations.

Regression

No.

Testing

Local build, app run.

Risk

Low.

Microsoft Reviewers: Open in CodeFlow

@h3xds1nz h3xds1nz requested review from a team as code owners July 14, 2024 12:14
@dotnet-policy-service dotnet-policy-service bot added PR metadata: Label to tag PRs, to facilitate with triage Community Contribution A label for all community Contributions labels Jul 14, 2024
@h3xds1nz h3xds1nz changed the title Replace boxing Stack in BamlReader, decrease allocs Replace boxing Stacks in BamlReader, decrease allocs, improve performance Jul 14, 2024
@harshit7962
Copy link
Member

@h3xds1nz Thank you for active contributions.

@h3xds1nz
Copy link
Member Author

@harshit7962 Happy to contribute!

@github-actions github-actions bot locked and limited conversation to collaborators Oct 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Community Contribution A label for all community Contributions PR metadata: Label to tag PRs, to facilitate with triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants