Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7727479
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T05:28:08+00:00 2026-06-01T05:28:08+00:00

In .NET 4.0+, a class SortedSet<T> has a method called GetViewBetween(l, r) , which

  • 0

In .NET 4.0+, a class SortedSet<T> has a method called GetViewBetween(l, r), which returns an interface view on a tree part containing all the values between the two specified. Given that SortedSet<T> is implemented as a red-black tree, I naturally expect it to run in O(log N) time. The similar method in C++ is std::set::lower_bound/upper_bound, in Java it’s TreeSet.headSet/tailSet, and they are logarithmic.

However, that is not true. The following code runs in 32 sec, whereas the equivalent O(log N) version of GetViewBetween would make this code run in 1-2 sec.

var s = new SortedSet<int>();
int n = 100000;
var rand = new Random(1000000007);
int sum = 0;
for (int i = 0; i < n; ++i) {
    s.Add(rand.Next());
    if (rand.Next() % 2 == 0) {
        int l = rand.Next(int.MaxValue / 2 - 10);
        int r = l + rand.Next(int.MaxValue / 2 - 10);
        var t = s.GetViewBetween(l, r);
        sum += t.Min;
    }
}
Console.WriteLine(sum);

I decompiled System.dll using dotPeek and here’s what I got:

public TreeSubSet(SortedSet<T> Underlying, T Min, T Max, bool lowerBoundActive, bool upperBoundActive)
    : base(Underlying.Comparer)
{
    this.underlying = Underlying;
    this.min = Min;
    this.max = Max;
    this.lBoundActive = lowerBoundActive;
    this.uBoundActive = upperBoundActive;
    this.root = this.underlying.FindRange(this.min, this.max, this.lBoundActive, this.uBoundActive);
    this.count = 0;
    this.version = -1;
    this.VersionCheckImpl();
}

internal SortedSet<T>.Node FindRange(T from, T to, bool lowerBoundActive, bool upperBoundActive)
{
  SortedSet<T>.Node node = this.root;
  while (node != null)
  {
    if (lowerBoundActive && this.comparer.Compare(from, node.Item) > 0)
    {
      node = node.Right;
    }
    else
    {
      if (!upperBoundActive || this.comparer.Compare(to, node.Item) >= 0)
        return node;
      node = node.Left;
    }
  }
  return (SortedSet<T>.Node) null;
}

private void VersionCheckImpl()
{
    if (this.version == this.underlying.version)
      return;
    this.root = this.underlying.FindRange(this.min, this.max, this.lBoundActive, this.uBoundActive);
    this.version = this.underlying.version;
    this.count = 0;
    base.InOrderTreeWalk((TreeWalkPredicate<T>) (n =>
    {
      SortedSet<T>.TreeSubSet temp_31 = this;
      int temp_34 = temp_31.count + 1;
      temp_31.count = temp_34;
      return true;
    }));
}

So, FindRange is obviously O(log N), but after that we call VersionCheckImpl… which does a linear-time traversal of the found subtree only for recounting its nodes!

  1. Why would you need to do that traversal all the time?
  2. Why .NET does not contain a O(log N) method for splitting a tree based on key, like C++ or Java? It is really helpful in lots of situations.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T05:28:09+00:00Added an answer on June 1, 2026 at 5:28 am

    about the version field

    UPDATE1:

    In my memory, a lot of (maybe all?) collections in BCL have the field version.

    First, about foreach:

    according to this msdn link

    The foreach statement repeats a group of embedded statements for each element in an array or an object collection. The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects.

    In many other collections, version is protected the data is not modified during the foreach

    For example, HashTable‘s MoveNext():

    public virtual bool MoveNext()
    {
        if (this.version != this.hashtable.version)
        {
            throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
        }
        //..........
    }
    

    But in the SortedSet<T>‘s MoveNext() method:

    public bool MoveNext()
    {
        this.tree.VersionCheck();
        if (this.version != this.tree.version)
        {
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
        }       
        //....
    }
    

    UPDATE2:

    But the O(N) loop maybe not only for version but also for the Count property.

    Because the MSDN of GetViewBetween said:

    This method returns a view of the range of elements that fall between lowerValue and upperValue, as defined by the comparer …. You can make changes in both the view and in the underlying SortedSet(Of T).

    So for every update it should be sync the count field (key and value are already same). To make sure the Count is correct

    There were two policies to reach the target:

    1. Microsoft’s
    2. Mono’s

    First, MS’s, in their code, they sacrifice the GetViewBetween()‘s performance and win the Count property’s performance.

    VersionCheckImpl() is one way to sync the Count property.

    Second, Mono. In mono’s code,GetViewBetween() is faster, but in their GetCount()method:

    internal override int GetCount ()
    {
        int count = 0;
        using (var e = set.tree.GetSuffixEnumerator (lower)) {
            while (e.MoveNext () && set.helper.Compare (upper, e.Current) >= 0)
                ++count;
        }
        return count;
    }
    

    It is always an O(N) operation!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a .NET class library containing a class with a method that performs
I have a .net class which makes a HTTP Request to a controller in
If I have a .Net class that is not part of any namespace then
I have a MustInherit .NET class which declares a constructor with an integer parameter.
I have a problem in a VB.Net class library which I have simplified greatly
I have a serializable POCO called DataUnification.ClientData.ClientInfo in a .NET class library project A
Which .net class is designed to hold an image data in memory. For example,
I have a C# .Net console application which calls a C++ .Net class library.
I have a VB.net class registered for COM interop which I'm instantiating within an
With .NET Reflector we can see many .NET Class Library method's implementations. But is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.