Adds FixedSizeBuilder type#154
Conversation
There was a problem hiding this comment.
No idea what changed here. Didn't do anything special other than use the project inside of Visual Studio
There was a problem hiding this comment.
Most likely the byte order mark s added (or removed). Editors don't show it, but it is nevertheless a change. I'm cool with you leaving it here.
There was a problem hiding this comment.
Just leave it. VS will keep doing this.
There was a problem hiding this comment.
Is it tilting at wind mills or not worth it to file a bug on VS?
There was a problem hiding this comment.
There is an extension that will make VS stop doing this.
There was a problem hiding this comment.
I think VS just likes the byte order mark to be there. I don't think it will ever remove it once added. Although I'm not sure.
There was a problem hiding this comment.
It might be a bit more 'user facing' to document this parameter as "The size of the array the Builder creates."
|
How about a test for calling Reset() multiple times in a row? |
|
OK. I'm done reviewing. Please ping when you've responded to all the feedback. |
|
Also, we should definitely get another MSFT signoff from the immutable team before merging this since it's very public API impacting and we don't have long to stabilize before releasing this library. |
|
@AArnott pushed a new commit. Took most of the feedback directly, added comments every where else |
There was a problem hiding this comment.
StyleCop guidelines for properties state the summary should begin with "Gets a value indicating whether" for boolean properties. So perhaps "Gets a value indicating whether this instance has not yet created an ImmutableArray{T} since it was last Reset or created."
|
Thanks, @jaredpar. Overall it looks really good. A few more comments that occurred to me on this iteration and replies to others. |
|
Thanks @AArnott. Pushed a new version which addresses items you raised. The one issue that I'm still worried about is the name |
There was a problem hiding this comment.
We usually define structs for public GetEnumerator() methods to reduce allocations.
Unless you want to go to that trouble, can you remove this method in favor of an explicit interface implementation for it? That way, we can add a public GetEnumerator() method later when and if the struct optimization is worthwhile.
There was a problem hiding this comment.
@AArnott I based this implementation off of ImmutableArray<T>+Builder which has this exact pattern. Should they both be changed?
There was a problem hiding this comment.
I think enumeration is rare and doesn't need to be optimized. In any case, we have O(1) indexing.
There was a problem hiding this comment.
@AArnott in the most recent push I changed this enumeration to just re-use the Enumerator type from ImmutableArray.
Are we still interested in making ImmutableArray.Builder have struct based enumeration? If so I can file an Issue to track that
|
Yes, the |
|
@AArnott push up a new version. Seems like our comments weren't lost with the most recent push. In case that changes though the one open issue that I'm aware of is whether or not to have Right now the pattern in |
|
Hmmm... I hear we're trying to avoid breaking changes at this point, and changing GetEnumerator on the other Builder would qualify as a breaking change. If it's already a non-struct on the other Builder then it's probably not a big issue. As you say, FixedSizeBuilder isn't meant as a first-class collection citizen so it's probably not a big deal. |
|
Closing this pull request since we've agreed to take another approach. |
|
I guess I closed this prematurely. Sorry about that. |
|
No problem, my email could have been clearer. Lesson of the day: don't type in a rush with a half open laptop in the middle of another meeting :) |
|
Can someone give an update on what the status of this is? |
There was a problem hiding this comment.
Should this be <see cref="ImmutableArray{T}.FixedLengthBuilder"/>?
There was a problem hiding this comment.
Either way works for the compiler, but yes, your prescribed syntax is easier to read.
The existing ImmutableArray<T> builder pattern through the Builder type uses a minimum of two array allocations to create a single ImmutableArray<T> instance. The ImmutableArray<T>.Builder type has an array field which is manipulated in much the same way as the array inside of List<T>. The call to ToImmutable on the builder creates a copy of this array at the current length and wraps the result in an ImmutableArray<T> This pattern is great for a number of sceanrios. For example when the length of the array is variable or the application has low memory pressure. There are many situations though where a no copy / single allocation solution would be advantageous. In particular where there are a known fixed number of elements to be converted to an array. There is no need for a double copy solution here because the final size is known in advance. All that is needed is for the array to be created, populated and then frozen in an ImmutableArray<T> instance. A good example of this need is Roslyn within Visual Studio. Roslyn is very careful to avoid unnecessary allocations, especially on hot paths. Many of the hot paths include building instances of ImmutableArray<T>. To avoid the double allocation Roslyn pools ImmutableArray<T>.Builder instances. This successfully avoids the double allocation but increases the overall Gen2 pressure in the system. This PR proposes to fix this by adding a no copy builder pattern: FixedSizeBuilder. This is a very simple wrapper around T[] which allows for the creation and population of the array without the ability to store a long term reference to the underlying array. Hence it can be safely converted to an ImmutableArray<T> without the need to copy the array. The builder can be reused for subsequent ImmutableArray<T> builds via the Reset method
eab3123 to
4a7346e
Compare
|
Based on the API review we decided to not pursue this option. |
The existing ImmutableArray builder pattern through the Builder type
uses a minimum of two array allocations to create a single
ImmutableArray instance. The ImmutableArray.Builder type has an
array field which is manipulated in much the same way as the array
inside of List. The call to ToImmutable on the builder creates a
copy of this array at the current length and wraps the result in an
ImmutableArray
This pattern is great for a number of sceanrios. For example when the
length of the array is variable or the application has low memory
pressure.
There are many situations though where a no copy / single allocation
solution would be advantageous. In particular where there are a known
fixed number of elements to be converted to an array. There is no need
for a double copy solution here because the final size is known in
advance. All that is needed is for the array to be created, populated
and then frozen in an ImmutableArray instance.
A good example of this need is Roslyn within Visual Studio. Roslyn is
very careful to avoid unnecessary allocations, especially on hot paths.
Many of the hot paths include building instances of ImmutableArray.
To avoid the double allocation Roslyn pools ImmutableArray.Builder
instances. This successfully avoids the double allocation but increases
the overall Gen2 pressure in the system.
This PR proposes to fix this by adding a no copy builder pattern:
FixedSizeBuilder. This is a very simple wrapper around T[] which allows
for the creation and population of the array without the ability to
store a long term reference to the underlying array. Hence it can be
safely converted to an ImmutableArray without the need to copy the
array.
The builder can be reused for subsequent ImmutableArray builds via
the Reset method