Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add optimization for ImmutableList<T>.AddRange #67

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -789,10 +789,7 @@ public void AddRange(IEnumerable<T> items)
{
Requires.NotNull(items, "items");

foreach (var item in items)
{
this.Root = this.Root.Add(item);
}
this.Root = this.Root.AddRange(items);
}

/// <summary>
Expand All @@ -812,10 +809,7 @@ public void InsertRange(int index, IEnumerable<T> items)
Requires.Range(index >= 0 && index <= this.Count, "index");
Requires.NotNull(items, "items");

foreach (T item in items)
{
this.Root = this.Root.Insert(index++, item);
}
this.Root = this.Root.InsertRange(index, items);
}

/// <summary>
Expand Down
27 changes: 20 additions & 7 deletions src/System.Collections.Immutable/tests/ImmutableListTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,35 @@ public void AddRangeOptimizationsTest()
[Fact]
public void AddRangeBalanceTest()
{
int randSeed = (int)DateTime.Now.Ticks;
Console.WriteLine("Random seed: {0}", randSeed);
var random = new Random(randSeed);

int expectedTotalSize = 0;

var list = ImmutableList<int>.Empty;

// Add batches of 32, 128 times, giving 4096 items
int batchSize = 32;
// Add some small batches, verifying balance after each
for (int i = 0; i < 128; i++)
{
list = list.AddRange(Enumerable.Range(batchSize * i + 1, batchSize));
list.Root.VerifyBalanced();
int batchSize = random.Next(32);
Console.WriteLine("Adding {0} elements to the list", batchSize);
list = list.AddRange(Enumerable.Range(expectedTotalSize+1, batchSize));
VerifyBalanced(list);
expectedTotalSize += batchSize;
}

// Add a single large batch to the end
list = list.AddRange(Enumerable.Range(4097, 61440));
Assert.Equal(Enumerable.Range(1, 65536), list);
int largeBatchSize = random.Next(32768) + 32768;
Console.WriteLine("Adding {0} elements to the list", largeBatchSize);
list = list.AddRange(Enumerable.Range(expectedTotalSize + 1, largeBatchSize));
VerifyBalanced(list);
expectedTotalSize += largeBatchSize;

list.Root.VerifyBalanced();
Assert.Equal(Enumerable.Range(1, expectedTotalSize), list);

// The following is not guaranteed by AVL trees but has not failed
// for any iterations of this test so far
// Ensure that tree height is no more than 1 from optimal
var root = list.Root as IBinaryTree<int>;

Expand Down