Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a custom SortedList enumerator to reduce allocations #1877

Merged
merged 8 commits into from Sep 7, 2018

Conversation

smoogipoo
Copy link
Contributor

@smoogipoo smoogipoo commented Sep 7, 2018

             Method |     Mean |     Error |    StdDev |    Gen 0 | Allocated |
------------------- |---------:|----------:|----------:|---------:|----------:|
 NoCustomEnumerator | 67.27 ms | 0.3430 ms | 0.3209 ms | 125.0000 |  400000 B |
   CustomEnumerator | 11.46 ms | 0.0927 ms | 0.0774 ms |        - |       0 B |
    [MemoryDiagnoser]
    public class Bench
    {
        private SortedList<int> sortedList = new SortedList<int>();
        private SortedListCustomEnumerator<int> sortedListCustomEnumerator = new SortedListCustomEnumerator<int>();

        [GlobalSetup]
        public void Setup()
        {
            for (int i = 0; i < 1000; i++)
            {
                sortedList.Add(i);
                sortedListCustomEnumerator.Add(i);
            }
        }

        [Benchmark]
        public void NoCustomEnumerator()
        {
            int finalValue = 0;

            for (int i = 0; i < 10000; i++)
            {
                foreach (var val in sortedList)
                    finalValue += val;
            }
        }

        [Benchmark]
        public void CustomEnumerator()
        {
            int finalValue = 0;

            for (int i = 0; i < 10000; i++)
            {
                foreach (var val in sortedListCustomEnumerator)
                    finalValue += val;
            }
        }
    }

Providing a custom enumerator makes the compiler not box. (https://stackoverflow.com/a/13752402)

Note that this is bypassed if one of the interfaces of SortedList<T> is ever used. E.g. this is bypassed by autosize, which references IReadOnlyList<T> AliveInternalChildren rather than SortedList<T> aliveInternalChildren. But this happens for List<T> too.

@peppy peppy merged commit f5728a4 into ppy:master Sep 7, 2018
internal Enumerator(SortedList<T> list)
{
this.list = list;
currentIndex = -1; // The first MoveNext() should bring the iterator to 0

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

@smoogipoo smoogipoo deleted the sortedlist-enumerator branch November 26, 2018 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants