<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Andrew Arnott</title><link>http://blogs.msdn.com/b/andrewarnottms/</link><description>News from my corner of the Visual Studio Project &amp;amp; Build team, programming tips, and solutions to common programming issues.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AndrewArnottMSDN" /><feedburner:info uri="andrewarnottmsdn" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Immutable Object Graph updates</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/zn9LnP3USZo/immutable-object-graph-updates.aspx</link><pubDate>Tue, 07 May 2013 15:31:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10416682</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10416682</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10416682</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2013/05/07/immutable-object-graph-updates.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2013/01/08/simple-immutable-objects.aspx" target="_blank"&gt;my last post&lt;/a&gt;, I introduced a T4 template that constructs efficient and quite capable immutable objects based on the simplest mutable type definition. I also mentioned that the published sample is (necessarily, ala T4 style) &lt;a href="https://github.com/AArnott/ImmutableObjectGraph" target="_blank"&gt;open source and hosted online&lt;/a&gt;. Two outsiders have already submitted pull requests that have been accepted. Some thoughtful feedback came in the form of comments to my last blog post as well. Thank you for your participation!&lt;/p&gt;  &lt;p&gt;The latest incarnation of the T4 template is substantially improved over what my last post described. Here are a few of them:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The immutable types now look and feel more like the &lt;a href="http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx" target="_blank"&gt;immutable collections&lt;/a&gt;, having static factory Create() methods instead of a static Default property. &lt;/li&gt;    &lt;li&gt;The With(…) multiple parameter method is easier to use. &lt;/li&gt;    &lt;li&gt;Partial methods give you the opportunity to set defaults for any property on your type.&lt;/li&gt;    &lt;li&gt;Certain fields can be marked as required, so that they are not optional parameters in the Create() method.&lt;/li&gt;    &lt;li&gt;Better support for immutable collections as members of the immutable types.&lt;/li&gt;    &lt;li&gt;The T4 template is broken up into several files, modeled as extensions, making it easier for you to add additional functionality to the template without having to fork the code in your own codebase, making future updates from the official project easier.&lt;/li&gt;    &lt;li&gt;Better support for a network of immutable objects referencing each other (the &lt;em&gt;graph&lt;/em&gt; part of the name).&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;#7 is where I expect to spend much of the future work on this effort.&lt;/p&gt;  &lt;p&gt;If this topic interests you, please take a fresh look at the latest version, and keep the feedback coming.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10416682" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=zn9LnP3USZo:Xn65M1KKbho:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=zn9LnP3USZo:Xn65M1KKbho:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=zn9LnP3USZo:Xn65M1KKbho:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=zn9LnP3USZo:Xn65M1KKbho:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=zn9LnP3USZo:Xn65M1KKbho:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/zn9LnP3USZo" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2013/05/07/immutable-object-graph-updates.aspx</feedburner:origLink></item><item><title>Simple immutable objects</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/gLt7HlKsVe4/simple-immutable-objects.aspx</link><pubDate>Tue, 08 Jan 2013 20:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10383276</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>19</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10383276</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10383276</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2013/01/08/simple-immutable-objects.aspx#comments</comments><description>&lt;p&gt;We&amp;rsquo;re all familiar with &lt;a href="http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx" target="_blank"&gt;immutable collections&lt;/a&gt; now. But immutability is only as immutable as it is deep. And an immutable collection of mutable objects may not provide the depth you&amp;rsquo;re looking for. So how can one create an immutable object?&lt;/p&gt;
&lt;p&gt;Suppose you would define the mutable version like this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class Fruit { 
    public string Color { get; set; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;An immutable version might be defined like this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public class ImmutableFruit {
	private readonly string color;
	
	public ImmutableFruit(string color) {
		this.color = color;
	}
	
	public string Color {
		get { return this.color; }
	}
}
&lt;/pre&gt;
&lt;p&gt;Now that&amp;rsquo;s fine for very simple objects. But once objects have several fields on them, the code you have to write to create a new object with just one or two fields changed gets tedious to write and maintain. So we can add a helper method for each property, that returns a new object with just that property changed. The method name convention is With&lt;em&gt;PropertyName&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We can make a couple more enhancements though. For classes with many properties, if you need to change several properties at once, allocating a new object with each property change as an intermediate step is wasteful and can contribute to &lt;a href="http://blog.nerdbank.net/search/label/GC" target="_blank"&gt;GC pressure&lt;/a&gt;. So we also add a With method that takes optional parameters for every property found on the class, allowing bulk property changes. Finally, for scenarios where you have several changes to make to the object but wish to do so in a multistep fashion (or just prefer property setters to With- method calls), we can construct a Builder class that allows mutation, and then can return the immutable copy when you&amp;rsquo;re done. This pattern is very similar to String and StringBuilder in the .NET Framework, and also like the recent immutable collections mentioned earlier.&lt;/p&gt;
&lt;p&gt;Another enhancement we can make is to make all constructors private. Why? Because a public constructor will end up allowing callers to allocate many copies of the default instance. Since these are immutable, this is just wasted memory and GC pressure. Alternatively, a static Default property that returns what a public default constructor would have but sharing the instance with all other callers, alleviates the pressure while also putting the caller in the &amp;ldquo;mood&amp;rdquo; for functional programming.&lt;/p&gt;
&lt;p&gt;What does the resulting immutable object look like? Considering it&amp;rsquo;s just a simple immutable object with one property, it&amp;rsquo;s rather large.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;public partial class Fruit {
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private static readonly Fruit DefaultInstance = new Fruit();
	
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly System.String color;
	
	/// &amp;lt;summary&amp;gt;Initializes a new instance of the Fruit class.&amp;lt;/summary&amp;gt;
	private Fruit()
	{
	}
	
	/// &amp;lt;summary&amp;gt;Initializes a new instance of the Fruit class.&amp;lt;/summary&amp;gt;
	private Fruit(System.String color)
	{
		this.color = color;
		this.Validate();
	}
	
	public static Fruit Default {
		get { return DefaultInstance; }
	}
	
	public System.String Color {
		get { return this.color; }
	}
	
	public Fruit WithColor(System.String value) {
		if (value == this.Color) {
			return this;
		}
	
		return new Fruit(value);
	}
	
	/// &amp;lt;summary&amp;gt;Returns a new instance of this object with any number of properties changed.&amp;lt;/summary&amp;gt;
	public Fruit With(
		System.String color = default(System.String),
		bool defaultColor = false) {
		return new Fruit(
				defaultColor ? default(System.String) : (color != default(System.String) ? color : this.Color));
	}
	
	public Builder ToBuilder() {
		return new Builder(this);
	}
	
	/// &amp;lt;summary&amp;gt;Normalizes and/or validates all properties on this object.&amp;lt;/summary&amp;gt;
	/// &amp;lt;exception type="ArgumentException"&amp;gt;Thrown if any properties have disallowed values.&amp;lt;/exception&amp;gt;
	partial void Validate();
	
	public partial class Builder {
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private Fruit immutable;
	
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private System.String color;
	
		internal Builder(Fruit immutable) {
			this.immutable = immutable;
	
			this.color = immutable.Color;
		}
	
		public System.String Color {
			get {
				return this.color;
			}
	
			set {
				if (this.color != value) {
					this.color = value;
					this.immutable = null;
				}
			}
		}
	
		public Fruit ToImmutable() {
			if (this.immutable == null) {
				this.immutable = Fruit.Default.With(
					this.color);
			}
	
			return this.immutable;
		}
	}
}&lt;/pre&gt;
&lt;p&gt;Of course adding more properties will be common, and the code will increase a bit more with each one. Since each added property means two new fields (one for the immutable type and one for the Builder), two new properties, and one new method and several other methods to update, this gets quite tedious to write and maintain.&lt;/p&gt;
&lt;p&gt;So what can we do to simplify immutable programming? After all, immutable programming is supposed to be easy, right? Why can&amp;rsquo;t authoring immutable types in C# be as easy as mutable types (or immutable types in F#)? There is a better way, using Visual Studio T4 templates.&lt;/p&gt;
&lt;p&gt;Consider this simple definition of a mutable type:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;class Fruit {
    string color;
}&lt;/pre&gt;
&lt;p&gt;We can leverage code generation to produce an immutable version of this class that fulfills all the patterns described above. And due to the built-in support for T4 in Visual Studio, the experience can be &lt;em&gt;just as easy&lt;/em&gt; as maintaining the above simple mutable type. Adding a property to the Fruit class is as simple as adding one line for the field in the above mutable type. Saving the updated file will immediately update the code generated immutable Fruit class, allowing you to get Intellisense and compile against the immutable version. T4 is built into Visual Studio, so it will already work for you today. Because code generation happens at design-time, you don&amp;rsquo;t need any additional support for it in any customized build system you may have.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve published &lt;a href="https://github.com/AArnott/ImmutableObjectGraph" target="_blank"&gt;the code generation tool&lt;/a&gt; in source form as a sample. You can see a live example of the &lt;a href="https://github.com/AArnott/ImmutableObjectGraph/blob/master/Fruit.tt" target="_blank"&gt;before&lt;/a&gt; and &lt;a href="https://github.com/AArnott/ImmutableObjectGraph/blob/master/Fruit.generated.cs" target="_blank"&gt;after&lt;/a&gt; code generation. The README in that project describes more and provides instructions for incorporating this tool into your source projects.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d like to add features as we go so your feedback is welcome.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10383276" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=gLt7HlKsVe4:YsEYPwk87lk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=gLt7HlKsVe4:YsEYPwk87lk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=gLt7HlKsVe4:YsEYPwk87lk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=gLt7HlKsVe4:YsEYPwk87lk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=gLt7HlKsVe4:YsEYPwk87lk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/gLt7HlKsVe4" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2013/01/08/simple-immutable-objects.aspx</feedburner:origLink></item><item><title>Immutable collection algorithmic complexity</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/dN7kmxGQPPY/immutable-collection-algorithmic-complexity.aspx</link><pubDate>Mon, 07 Jan 2013 14:19:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10382820</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10382820</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10382820</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2013/01/07/immutable-collection-algorithmic-complexity.aspx#comments</comments><description>&lt;p&gt;I received some feedback from &lt;a href="http://blogs.msdn.com/b/bclteam/archive/2012/12/18/preview-of-immutable-collections-released-on-nuget.aspx" target="_blank"&gt;my recent BCL blog post on the prerelease of the immutable collections&lt;/a&gt; that my algorithm complexity table left a few important entries out. Here is the table again, with more data filled in (particularly around list indexer lookup and enumeration):&lt;/p&gt;  &lt;table border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;th&gt;         &lt;p&gt;&amp;#160;&lt;/p&gt;       &lt;/th&gt;        &lt;th&gt;         &lt;p&gt;Mutable (amortized)&lt;/p&gt;       &lt;/th&gt;        &lt;th&gt;         &lt;p&gt;Mutable (worst case)&lt;/p&gt;       &lt;/th&gt;        &lt;th&gt;         &lt;p&gt;Immutable&lt;/p&gt;       &lt;/th&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Stack.Push&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Queue.Enqueue&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;List.Add&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;List lookup by index&lt;/td&gt;        &lt;td&gt;O(1)&lt;/td&gt;        &lt;td&gt;O(1)&lt;/td&gt;        &lt;td&gt;O(log n)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;List enumeration&lt;/td&gt;        &lt;td&gt;O(n)&lt;/td&gt;        &lt;td&gt;O(n)&lt;/td&gt;        &lt;td&gt;O(n)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;HashSet.Add, lookup&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;SortedSet.Add&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;Dictionary.Add&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(1)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Dictionary lookup&lt;/td&gt;        &lt;td&gt;O(1)&lt;/td&gt;        &lt;td&gt;O(1) – or strictly O(n)&lt;/td&gt;        &lt;td&gt;O(log n)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;SortedDictionary.Add&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(n log n)&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p&gt;O(log n)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;A noteworthy trait to call out here is that where a List&amp;lt;T&amp;gt; can be efficiently enumerated using either a &lt;strong&gt;for &lt;/strong&gt;loop or a &lt;strong&gt;foreach &lt;/strong&gt;loop, ImmutableList&amp;lt;T&amp;gt; does a poor job inside a &lt;strong&gt;for&lt;/strong&gt; loop, due to its O(log n) time for its indexer. It does fine when using &lt;strong&gt;foreach&lt;/strong&gt; however. This is because ImmutableList&amp;lt;T&amp;gt; uses a binary tree to store its data instead of a simple array like List&amp;lt;T&amp;gt; uses. An array can be very quickly indexed into, whereas a binary tree must be walked down until the node with the desired index is found.&lt;/p&gt;  &lt;p&gt;Another point to call out from the above table is that SortedSet&amp;lt;T&amp;gt; has the &lt;em&gt;same&lt;/em&gt; complexity as ImmutableSortedSet&amp;lt;T&amp;gt;, and in fact in perf tests they show up as pretty close. That’s because they both use binary trees. The significant difference of course is that ImmutableSortedSet&amp;lt;T&amp;gt; uses an immutable one. Since ImmutableSortedSet&amp;lt;T&amp;gt; also offers a Builder class that allows mutation, you &lt;em&gt;can&lt;/em&gt; have your immutability and performance too. Woot.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10382820" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=dN7kmxGQPPY:9rpCfoQyKLw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=dN7kmxGQPPY:9rpCfoQyKLw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=dN7kmxGQPPY:9rpCfoQyKLw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=dN7kmxGQPPY:9rpCfoQyKLw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=dN7kmxGQPPY:9rpCfoQyKLw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/dN7kmxGQPPY" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2013/01/07/immutable-collection-algorithmic-complexity.aspx</feedburner:origLink></item><item><title>The cost of context switches</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/S0Clg2R35k8/the-cost-of-context-switches.aspx</link><pubDate>Fri, 28 Dec 2012 17:56:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10381186</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10381186</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10381186</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2012/12/28/the-cost-of-context-switches.aspx#comments</comments><description>&lt;p&gt;Context switches are not free. But how expensive are they? I wrote a small program to find out, and I’m sharing the program and its results here.&lt;/p&gt;  &lt;p&gt;I focused on purely context switches (no work is actually performed between context switches). So it’s not a real-world scenario, but it really brings out the hidden costs. Below are the results 500,000 context switches performing no work between each one.&lt;/p&gt;  &lt;pre&gt;Executing 500000 work cycles of 0 iterations each, in different ways...
Scenario            Total time (ms)     Time per unit (µs)
No-switch           0                   0.0002
Async w/o yield     67                  0.0353
Async w/ yield      664                 0.349
Thread switches     5215                2.7412&lt;/pre&gt;

&lt;p&gt;Notice how with each kind, the order of magnitude of the overhead increases. The code below will help you understand what each each scenario name actually means. Then we add a bit of work (counting to 500) per context switch, which is closer to a possible real-world work load (although relatively lightweight) that might occur for a given context:&lt;/p&gt;

&lt;pre&gt;Executing 500000 work cycles of 500 iterations each, in different ways...
Scenario            Total time (ms)     Time per unit (µs)
No-switch           380                 0.1998
Async w/o yield     368                 0.1935
Async w/ yield      832                 0.4374
Thread switches     5185                2.7257&lt;/pre&gt;

&lt;p&gt;Suddenly no context switch and async methods all share an order of magnitude, while thread switches still takes significantly longer. In fact closely comparing shows that Async w/o yield is faster than no switch at all. This of course is ludicrous and can be written off as noise. But several runs produced the same result, so we can glean from this that when doing even a small amount of work per context switch, that the no-yield async method adds insignificant overhead.&lt;/p&gt;

&lt;p&gt;Following is the application that produced the above results.&lt;/p&gt;

&lt;pre class="prettyprint"&gt;using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

class Program {
	const int unitSize = 500;
	const int workSize = 500000;
	const string spacing = &amp;quot;{0,-20}{1,-20}{2,-20}&amp;quot;;

	private static void Main(string[] args) {
		Console.WriteLine(&amp;quot;Executing {0} work cycles of {1} iterations each, in different ways...&amp;quot;, workSize, unitSize);

		Console.WriteLine(spacing, &amp;quot;Scenario&amp;quot;, &amp;quot;Total time (ms)&amp;quot;, &amp;quot;Time per unit (μs)&amp;quot;);
		Scenario(&amp;quot;No-switch&amp;quot;, DoSync);
		Scenario(&amp;quot;Async w/o yield&amp;quot;, DoAsyncNoYield);
		Scenario(&amp;quot;Async w/ yield&amp;quot;, DoAsyncWithYield);
		Scenario(&amp;quot;Thread switches&amp;quot;, ThreadSwitch);
	}

	static void Scenario(string name, Action operation) {
		GC.Collect();
		operation(); // warm it up
		var timer = Stopwatch.StartNew();
		operation();
		timer.Stop();
		Console.WriteLine(spacing, name, timer.ElapsedMilliseconds, MicroSecondsPerItem(timer));
	}

	static void ThreadSwitch() {
		int workRemaining = workSize;
		var evt = new AutoResetEvent(true);
		ThreadStart worker = () =&amp;gt; {
			while (workRemaining &amp;gt; 0) {
				evt.WaitOne();
				workRemaining--;
				WorkUnit();
				evt.Set();
			}
		};

		var threads = new Thread[Environment.ProcessorCount];
		for (int i = 0; i &amp;lt; threads.Length; i++) {
			threads[i] = new Thread(worker);
			threads[i].Start();
		}

		for (int i = 0; i &amp;lt; threads.Length; i++) {
			threads[i].Join();
		}
	}

	static void DoAsyncNoYield() {
		var tcs = new TaskCompletionSource&amp;lt;object&amp;gt;();
		tcs.SetResult(null);
		var task = tcs.Task;
		Task.Run(
			async delegate {
				int workRemaining = workSize;
				while (--workRemaining &amp;gt;= 0) {
					await NoYieldHelper(task);
				}
			}).Wait();
	}

	static async Task NoYieldHelper(Task task) {
		WorkUnit();
		await task;
	}

	static void DoAsyncWithYield() {
		Task.Run(
			async delegate {
				int workRemaining = workSize;
				while (--workRemaining &amp;gt;= 0) {
					WorkUnit();
					await Task.Yield();
				}
			}).Wait();
	}

	static void DoSync() {
		int workRemaining = workSize;
		while (--workRemaining &amp;gt;= 0) {
			WorkUnit();
		}
	}

	private static double MicroSecondsPerItem(Stopwatch timer) {
		var ticksPerItem = (double)timer.ElapsedTicks / workSize;
		var microSecondsPerItem = TimeSpan.FromTicks((long)(ticksPerItem * 1000)).TotalMilliseconds;
		return microSecondsPerItem;
	}

	static void WorkUnit() {
		for (int i = 0; i &amp;lt; unitSize; i++) {
		}
	}
}
&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10381186" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=S0Clg2R35k8:0j5GqtnOlAg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=S0Clg2R35k8:0j5GqtnOlAg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=S0Clg2R35k8:0j5GqtnOlAg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=S0Clg2R35k8:0j5GqtnOlAg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=S0Clg2R35k8:0j5GqtnOlAg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/S0Clg2R35k8" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/async/">async</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2012/12/28/the-cost-of-context-switches.aspx</feedburner:origLink></item><item><title>Immutable collections now available</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/YP-KpoaCVEM/immutable-collections-now-available.aspx</link><pubDate>Thu, 20 Dec 2012 03:28:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10379642</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10379642</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10379642</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2012/12/20/immutable-collections-now-available.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/30/immutable-collections-with-mutable-performance.aspx" target="_blank"&gt;In previous posts&lt;/a&gt;, I discussed immutable collections. I’m pleased to say they are now available. Read my announcement on the &lt;a href="http://bit.ly/12AXD77" target="_blank"&gt;BCL blog&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10379642" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YP-KpoaCVEM:WXsd06A3ny8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=YP-KpoaCVEM:WXsd06A3ny8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YP-KpoaCVEM:WXsd06A3ny8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=YP-KpoaCVEM:WXsd06A3ny8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YP-KpoaCVEM:WXsd06A3ny8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/YP-KpoaCVEM" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2012/12/20/immutable-collections-now-available.aspx</feedburner:origLink></item><item><title>Update to Visual C++ 2012 Debugger launch extension template</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/hW0c2I2Tlls/update-to-visual-c-2012-debugger-launch-extension-template.aspx</link><pubDate>Fri, 08 Jun 2012 18:11:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10317511</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10317511</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10317511</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/08/update-to-visual-c-2012-debugger-launch-extension-template.aspx#comments</comments><description>&lt;p&gt;A few days ago I posted about an &lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/05/visual-c-2012-debugger-extensibility.aspx"&gt;updated Visual C++ 2012 debugger extensibility project template&lt;/a&gt;.&amp;#160; Since then, I realized it had a couple of issues that prevented it from working out of the box.&amp;#160; With those fixed, I also added a demonstration of how to read project properties that aren’t specifically dedicated to debugger support.&amp;#160; For example, if you want to determine the target framework of the project, or read the TargetPath property, that requires that you read properties that aren’t in your own debugger property page.&amp;#160; The &lt;a href="http://visualstudiogallery.msdn.microsoft.com/8d2faf2c-3937-489a-9e0a-c43ff26ca427"&gt;project template on the Visual Studio Gallery&lt;/a&gt; is already updated with these new capabilities.&amp;#160; &lt;/p&gt;  &lt;p&gt;Unfortunately there’s a slight new problem with the initial project expansion (when you use New Project to create a project based on the template), but the opening web page that explains next steps tells you the workaround.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10317511" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=hW0c2I2Tlls:W0mjIbB2YDM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=hW0c2I2Tlls:W0mjIbB2YDM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=hW0c2I2Tlls:W0mjIbB2YDM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=hW0c2I2Tlls:W0mjIbB2YDM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=hW0c2I2Tlls:W0mjIbB2YDM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/hW0c2I2Tlls" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/C_2B002B00_/">C++</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/CPS/">CPS</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/08/update-to-visual-c-2012-debugger-launch-extension-template.aspx</feedburner:origLink></item><item><title>Enable C++ and Javascript project system tracing</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/ce6I_lSJ1fo/enable-c-and-javascript-project-system-tracing.aspx</link><pubDate>Thu, 07 Jun 2012 21:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10316979</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10316979</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10316979</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/07/enable-c-and-javascript-project-system-tracing.aspx#comments</comments><description>&lt;p&gt;I&amp;rsquo;ve previously posted on &lt;a href="http://blogs.msdn.com/b/vsproject/archive/2009/07/21/enable-c-project-system-logging.aspx"&gt;how to enable logging in the C++ project system in Visual Studio 2010&lt;/a&gt;.&amp;nbsp; In Visual Studio 2012 we&amp;rsquo;ve changed the way the Common Project System (aka &amp;ldquo;CPS&amp;rdquo;) emits trace messages so below I introduce an updated xml snippet that works in Visual Studio 2012.&amp;nbsp; Since CPS is now the project system driving JavaScript as well, the below xml snippet impacts that as well.&lt;/p&gt; &lt;p&gt;To enable tracing, add the following xml block to devenv.exe.config file directly under the &amp;lt;configuration&amp;gt; root node, &lt;strong&gt;after the &amp;lt;/configSections&amp;gt; end tag.&lt;/strong&gt; Make sure to make a backup first so that you can revert back in case something goes wrong.&amp;nbsp; You may need to change "Warning" below with "Verbose" if you want verbose logging.&lt;/p&gt; &lt;pre class="prettyprint language-xml"&gt;&amp;lt;system.diagnostics&amp;gt;
    &amp;lt;sources&amp;gt;
        &amp;lt;source name="CPS" switchName="CPS" switchType="System.Diagnostics.SourceSwitch"&amp;gt;
            &amp;lt;listeners&amp;gt;
                &amp;lt;add name="cpsFileLogger"/&amp;gt;
            &amp;lt;/listeners&amp;gt;
        &amp;lt;/source&amp;gt;
    &amp;lt;/sources&amp;gt;
    &amp;lt;switches&amp;gt;
        &amp;lt;add name="CPS" value="&lt;strong&gt;&lt;span style="background-color: #ffff00;"&gt;Warning&lt;/span&gt;&lt;/strong&gt;"/&amp;gt;
    &amp;lt;/switches&amp;gt;
    &amp;lt;sharedListeners&amp;gt;
        &amp;lt;add name="cpsFileLogger" type="System.Diagnostics.TextWriterTraceListener" initializeData="&lt;strong&gt;&lt;span style="background-color: #ffff00;"&gt;c:\temp\devenv-cps.log&lt;/span&gt;&lt;/strong&gt;"&amp;gt;
            &amp;lt;filter type="System.Diagnostics.EventTypeFilter" initializeData="&lt;strong&gt;&lt;span style="background-color: #ffff00;"&gt;Warning&lt;/span&gt;&lt;/strong&gt;"/&amp;gt;
        &amp;lt;/add&amp;gt;
    &amp;lt;/sharedListeners&amp;gt;
    &amp;lt;trace autoflush="true" indentsize="4" /&amp;gt;
&amp;lt;/system.diagnostics&amp;gt;
&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10316979" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=ce6I_lSJ1fo:evSmVCaH7qg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=ce6I_lSJ1fo:evSmVCaH7qg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=ce6I_lSJ1fo:evSmVCaH7qg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=ce6I_lSJ1fo:evSmVCaH7qg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=ce6I_lSJ1fo:evSmVCaH7qg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/ce6I_lSJ1fo" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Visual+Studio/">Visual Studio</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/C_2B002B00_/">C++</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/CPS/">CPS</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/07/enable-c-and-javascript-project-system-tracing.aspx</feedburner:origLink></item><item><title>Visual C++ 2012 Debugger Extensibility</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/Iiw8ZU_VmF4/visual-c-2012-debugger-extensibility.aspx</link><pubDate>Tue, 05 Jun 2012 17:56:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10315379</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10315379</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10315379</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/05/visual-c-2012-debugger-extensibility.aspx#comments</comments><description>&lt;p&gt;Back &lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2010/02/12/vc-debugger-extensibility.aspx"&gt;in Visual C++ 2010 we introduced debugger extensibility&lt;/a&gt; so that third party vendors can either add new debugger engines or new ways of launching existing debugger engines for C++ projects.&amp;#160; &lt;/p&gt;  &lt;p&gt;In Visual C++ 2012 this debugger extensibility has been updated.&amp;#160; Any previous extensions that were compiled against Visual C++ 2010 will have to be recompiled after updating your source code to implement the new interface.&amp;#160; Visual Studio doesn’t usually break backward compatibility, particularly for extension points, and we realize this can cause some additional work for our partners.&amp;#160; This interface in both its 2010 and 2012 versions isn’t considered “final”, so while we knew our partners need this extensibility point in these intermediate forms, we appreciate your patience and understanding as we evolve what we hope will become a common extensible platform for project systems.&lt;/p&gt;  &lt;p&gt;With that out of the way, please check out the new &lt;a href="http://visualstudiogallery.msdn.microsoft.com/8d2faf2c-3937-489a-9e0a-c43ff26ca427"&gt;Visual C++ 2012 Debugger Launch Extension&lt;/a&gt; project template on the Visual Studio Gallery to get started.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10315379" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=Iiw8ZU_VmF4:0hwB7e7yX0g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=Iiw8ZU_VmF4:0hwB7e7yX0g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=Iiw8ZU_VmF4:0hwB7e7yX0g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=Iiw8ZU_VmF4:0hwB7e7yX0g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=Iiw8ZU_VmF4:0hwB7e7yX0g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/Iiw8ZU_VmF4" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Visual+Studio/">Visual Studio</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/C_2B002B00_/">C++</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2012/06/05/visual-c-2012-debugger-extensibility.aspx</feedburner:origLink></item><item><title>Immutable collections with mutable performance</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/WbpMt_qKTeQ/immutable-collections-with-mutable-performance.aspx</link><pubDate>Tue, 30 Aug 2011 03:33:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10202238</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10202238</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10202238</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/30/immutable-collections-with-mutable-performance.aspx#comments</comments><description>&lt;p&gt;In my &lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/22/read-only-frozen-and-immutable-types-and-collections.aspx"&gt;last post&lt;/a&gt;, I detailed the differences among read/write, read only, frozen and immutable collection types.&amp;#160; I described how immutable collections come with a hit to the garbage collector due to the garbage they generate during mutations.&amp;#160; I have a very positive update on that topic.&lt;/p&gt;  &lt;p&gt;My previous implementation for the immutable collections used a truly immutable binary tree as its backing data structure.&amp;#160; As a result, every individual mutation required a spine rewrite where (log n) nodes were recreated.&amp;#160; For a batch of &lt;em&gt;m&lt;/em&gt; changes, this meant &lt;em&gt;m log n&lt;/em&gt; objects were created and immediately discarded.&amp;#160; That’s a &lt;em&gt;lot&lt;/em&gt; of garbage.&amp;#160; And all those memory allocations (and GC interruptions) hurt performance to the tune of about being twice as slow as mutable collections.&lt;/p&gt;  &lt;p&gt;By changing the collections to use a freezable binary tree data structure, spine rewrites retain new nodes that are mutable until the (bulk) operation has completed.&amp;#160; As a result, only &lt;em&gt;log n&lt;/em&gt; nodes are created instead of &lt;em&gt;m log n&lt;/em&gt;.&amp;#160; And those new nodes aren’t garbage: they’re the important “new” part of the updated collection.&amp;#160; By eliminating all garbage from intermediate steps of mutations, I’ve measured a 91% drop in overall memory allocation (the remaining 9% is not garbage) and a 50% improvement in performance.&amp;#160; This brings performance and memory load of immutable collections on par with the mutable collections, while retaining all their immutable properties that make them so attractive.&lt;/p&gt;  &lt;p&gt;Is there anything worse about the immutable collections then?&amp;#160; Yes, if you have rapid changes to the collections that you make individually (you don’t batch them with AddRange or some similar method) then you still may produce a lot of garbage assuming you release each version as you update it, whereas a mutable collection may have vacant memory slots it can fill when you add elements, immutable collections do not, and thus allocate memory for every element addition.&amp;#160; But as discussed in my previous post, this “slack space” is also a point against mutable collections as it wastes memory that isn’t reclaimable until to release the entire collection.&lt;/p&gt;  &lt;p&gt;We expect (not promise) to ship these highly tuned immutable collections as a public CTP release soon.&amp;#160; I’m stoked.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10202238" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=WbpMt_qKTeQ:593JKbF_xFg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=WbpMt_qKTeQ:593JKbF_xFg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=WbpMt_qKTeQ:593JKbF_xFg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=WbpMt_qKTeQ:593JKbF_xFg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=WbpMt_qKTeQ:593JKbF_xFg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/WbpMt_qKTeQ" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/30/immutable-collections-with-mutable-performance.aspx</feedburner:origLink></item><item><title>Read only, frozen, and immutable collections</title><link>http://feedproxy.google.com/~r/AndrewArnottMSDN/~3/YEQH2HksZjQ/read-only-frozen-and-immutable-types-and-collections.aspx</link><pubDate>Sun, 21 Aug 2011 23:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10198307</guid><dc:creator>Andrew L Arnott</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.msdn.com/b/andrewarnottms/rsscomments.aspx?WeblogPostID=10198307</wfw:commentRss><wfw:comment>http://blogs.msdn.com/b/andrewarnottms/commentapi.aspx?WeblogPostID=10198307</wfw:comment><comments>http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/22/read-only-frozen-and-immutable-types-and-collections.aspx#comments</comments><description>&lt;p&gt;[Update: &lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/30/immutable-collections-with-mutable-performance.aspx"&gt;a more recent post with new data on attainable performance of immutable collections&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;The topics of immutability and functional programming has fascinated me lately.&amp;nbsp; Mostly because of my work on the Visual Studio Common Project System (CPS) which is a large, highly multi-threaded code base that only remains sane because of its reliance on immutable types in many areas.&lt;/p&gt;
&lt;p&gt;In my research and conversations on this topic, I&amp;rsquo;ve learned to appreciate the differences between several adjectives often used interchangeably among programmers that I&amp;rsquo;d like to share with you, detailing the differences including some pros and cons of each.&amp;nbsp; At the bottom of the post I include a summary table and my own personal verdict for what kinds of collections (mutable and immutable) I prefer.&lt;/p&gt;
&lt;p&gt;Although the principles here apply to any type in any language and platform, I&amp;rsquo;ll be using for some references and examples the collection types in the .NET base class library.&lt;/p&gt;
&lt;p&gt;First a little terminology as I will use it in this post:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mutable (a.k.a read/write): a collection or type that allows for in-place updates that anyone with a reference to that object may observe.&lt;/li&gt;
&lt;li&gt;Immutable: a collection or type that cannot be changed at all, but can be efficiently mutated by allocating a new collection that shares much of the same memory with the original, but has new memory describing the change.&lt;/li&gt;
&lt;li&gt;Freezable: a collection or type that is mutable until some point in time when it is frozen, after which it cannot be changed.&lt;/li&gt;
&lt;li&gt;Read only: a reference whose type does not permit mutation of the underlying data, which is usually &lt;em&gt;mutable&lt;/em&gt; by another reference.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;The de facto read only standards in .NET&lt;/h4&gt;
&lt;p&gt;There are not yet any freezable or immutable collections included in the&amp;nbsp; .NET base class library.&amp;nbsp; But we have a couple of read-only views of data, as outlined below.&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;De facto standard #1: IEnumerable&amp;lt;T&amp;gt;&lt;/h5&gt;
&lt;p&gt;Often considered a convenient way to express data in a read-only way, IEnumerable&amp;lt;T&amp;gt; actually provides very few, if any, guarantees and almost no protections.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NO thread-safety to issuer or receiver. If the underlying collection changes while being enumerated from another thread, data corruption may result or exceptions may be thrown.&lt;/li&gt;
&lt;li&gt;NO immutability guarantee to the receiver. The underlying collection may be changed.&lt;/li&gt;
&lt;li&gt;NO immutability guarantee to the issuer. The receiver may cast the enumerable to ICollection or some other read/write type and may mutate the data through that interface if the underlying object allows it.&lt;/li&gt;
&lt;li&gt;NO performance guarantee to the receiver. The enumerable may represent a deferred execution query (LINQ for example) that may incur significant cost including network overhead with each enumeration.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avoiding these shortcomings usually requires enumerating exactly once into a cloned collection, which comes with a perf and memory hit, and doesn&amp;rsquo;t entirely protect you from thread-safety issues that may occur during that one enumeration.&lt;/p&gt;
&lt;h5&gt;De facto standard #2: ReadOnlyCollection&amp;lt;T&amp;gt;&lt;/h5&gt;
&lt;p&gt;Somewhat misleadingly named, this collection is neither immutable nor a general collection. It is merely a wrapper around a mutable list.&amp;nbsp; Perhaps a more accurate name would be ReadOnlyListFacade&amp;lt;T&amp;gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This collection type is better than IEnumerable&amp;lt;T&amp;gt; in several ways, but still deficient in others:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YES, immutable guarantee to the issuer.&amp;nbsp; The collection owner never releases a reference to the mutable collection, as the ReadOnlyCollection&amp;lt;T&amp;gt; is a genuine &lt;em&gt;wrapper&lt;/em&gt; around the mutable data, making it impossible for a receiver of the collection to mutate the data.&lt;/li&gt;
&lt;li&gt;YES, thread safety to the issuer, since the receiver cannot mutate the data, the underlying collection may be mutated without fear that the issuer with throw an exception or corrupt its own data.&lt;/li&gt;
&lt;li&gt;YES, reasonable performance guarantee to the receiver.&amp;nbsp; The IList&amp;lt;T&amp;gt; that the ReadOnlyCollection&amp;lt;T&amp;gt; wraps is virtually never populated via deferred execution.&amp;nbsp; Therefore enumerating the ReadOnlyCollection&amp;lt;T&amp;gt; repeatedly can generally be done with high performance and without side effects.&lt;/li&gt;
&lt;li&gt;NO thread-safety to the receiver.&amp;nbsp; If the receiver is reading the ReadOnlyCollection&amp;lt;T&amp;gt; while the issuer is mutating the underlying collection, the client may get an exception or perhaps even incorrectly perceive the contents of the collection.&lt;/li&gt;
&lt;li&gt;NO immutability guarantee to the receiver. The underlying collection may be changed.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Considerations among collections&lt;/h4&gt;
&lt;h5&gt;Thread-safety&lt;/h5&gt;
&lt;p&gt;Collections that are not thread-safe cannot be made thread-safe in a shareable way.&amp;nbsp; For example, although you can put lock { } statements around all uses of a collection to make it thread-safe, you cannot share references to your collection or any part of it outside your class because outside holders of that reference will not synchronize access to it with the same lock object you do (and ICollection.SyncRoot seems increasingly unpopular if it were ever known at all).&amp;nbsp; This suggests the importance of thread-safety built into collection classes.&lt;/p&gt;
&lt;h5&gt;Freezable collections&lt;/h5&gt;
&lt;p&gt;There are no freezable collection types in .NET (yet anyway).&amp;nbsp; So a discussion on them is somewhat speculative.&amp;nbsp; If the traditional List&amp;lt;T&amp;gt; class were to pick up a &amp;ldquo;Freeze()&amp;rdquo; method and an &amp;ldquo;IsFrozen&amp;rdquo; property, there would still be missing a type-safe way of communicating that a method expects or returns a frozen collection. You would have to perform a runtime check to see what is allowed or provided. Collection types that guarantee immutability are preferable for this purpose. If a method accepts an immutable collection parameter or returns an immutable collection, you have 100% confidence that that collection cannot ever change, period. If a List&amp;lt;T&amp;gt;.Freeze() method returned a FrozenList&amp;lt;T&amp;gt; object, and both the original List&amp;lt;T&amp;gt; and the FrozenList&amp;lt;T&amp;gt; pointed to the same data structure that could no longer be changed, that would provide a type-safe way of requiring or guaranteeing immutable data, however.&lt;/p&gt;
&lt;p&gt;While one might consider that guarantee more theoretically aesthetic than practically useful, I can speak from some experience now that I avoid a lot of collection cloning code (and the perf problems that showed up as a result) because I &lt;em&gt;know&lt;/em&gt; that a collection I just received cannot possibly be changed. It&amp;rsquo;s gotten to the point that when I see a method accepting an IList&amp;lt;T&amp;gt; I ask myself &amp;ldquo;Why? Is that method expecting the caller to further mutate that list during or after its invocation and that the method will need to see that mutation?&amp;rdquo; Call me a functional programming geek, but if a method does not expect the caller the tamper with a collection that it passes to the method, I now greatly prefer to see IImmutableList&amp;lt;T&amp;gt; as the method parameter.&lt;/p&gt;
&lt;p&gt;Before freezing, freezable collections offer the high construction performance and compact memory utilization of traditional mutable collections.&amp;nbsp; After freezing, any further mutation requires shallow cloning of the entire collection, with the perf and memory hit that comes with it.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One possible danger of using a collection that is freezable (but unfrozen) is that someone you share a reference to the collection with might want an immutable copy of the collection and may freeze the collection behind your back, not realizing that your class still &amp;ldquo;owns&amp;rdquo; the collection and thus expects it to not be frozen.&lt;/p&gt;
&lt;h5&gt;Performance&lt;/h5&gt;
&lt;p&gt;The performance of mutable collections, particularly when they are initially sized adequate for their contents, can&amp;rsquo;t be beat by immutable collections.&amp;nbsp; However the performance of immutable collections can be remarkably good.&amp;nbsp; Much better than one might expect, and certainly good enough for due consideration in your design.&lt;/p&gt;
&lt;p&gt;Immutable collections primary shortcoming is that raw add performance tends to be 2-3X slower than the amortized cost of its mutable collection counterparts.&amp;nbsp; This is chiefly due to the mandatory &amp;ldquo;spine rewrite&amp;rdquo; of the binary tree and the memory allocations that go along with it.&amp;nbsp; I just compared against &lt;em&gt;amortized&lt;/em&gt; cost of mutable collections because mutable collections have the shortcoming of occasionally breaking the bounds of their pre-allocated memory, which usually means allocating twice as much and then copying all the data from the old location to the new location.&lt;/p&gt;
&lt;p&gt;Before you write off immutable collections due to their perf impact on initialization, keep in mind that this may rarely be where the performance problems in apps come from.&amp;nbsp; In my experience the perf problems never come from creating a new collection, but rather from cloning a collection within a lock to provide immutability and thread-safety guarantees, which completely vanish when you switch to genuinely immutable collections.&amp;nbsp; Also, the spine rewrite that leads to the slower fill performance can be avoided by using an immutable collection that optimizes around that scenario, as described in the below discussion on garbage collection.&lt;/p&gt;
&lt;h5&gt;&lt;/h5&gt;
&lt;h5&gt;Memory efficiency&lt;/h5&gt;
&lt;p&gt;When dealing with collections, there&amp;rsquo;s no tighter data structure than an array, which is the underlying data structure of choice for most flat collections.&amp;nbsp; It has almost no overhead beyond the data stored, and that&amp;rsquo;s hard to beat.&amp;nbsp; On the other hand, since arrays have fixed size, it usually means there is memory wasted in the slack between the last element in the collection and the last slot in the preallocated array.&amp;nbsp; And when you have more elements than you have slots in the array, the array growth algorithm tends to be to allocate a new array of double the length and move all the data over, which means even more slack space wasting your memory.&lt;/p&gt;
&lt;p&gt;Immutable collections can&amp;rsquo;t afford (in memory or performance) to use arrays because changing the collection would require cloning the array every time.&amp;nbsp; Instead, performant immutable collections can use binary trees that allow for incremental, non-mutating updates to the collection.&amp;nbsp; Without going deep into the theory of it, it allows (for example) an immutable collection of 500 elements to be mutated into a &lt;em&gt;new&lt;/em&gt; collection with one element added or removed while sharing almost all the memory between the two collections.&amp;nbsp; But because binary tree data structures require a heap-allocated &amp;ldquo;node&amp;rdquo; to represent each element in the array, with references to two other nodes in the tree, there is an overhead of at least 12 bytes per element in immutable collections.&lt;/p&gt;
&lt;h5&gt;Garbage generation and collection&lt;/h5&gt;
&lt;p&gt;Garbage generation is also an important concern when considering the memory impact of immutable collections.&amp;nbsp; Every mutation of an immutable collection necessarily allocates more memory.&amp;nbsp; And while most memory is shared across the different versions of the collection, when a particular version of a collection is no longer referenced, it automatically gets garbage collected.&amp;nbsp; This is a convenient feature of immutable collections in that they optimally share and automatically free memory.&amp;nbsp; However, since each mutation of the collection makes the last version of the collection uninteresting and thus available for garbage collection, it generally means that more garbage is produced than for the mutable counterpart.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s the problem with allocating objects if they are freed as soon as they are not used any more?&amp;nbsp; The problem comes at garbage collection time. The more memory you allocate and release, the more frequently the garbage collector has to run, which usually suspends all other threads in your .NET application, potentially causing perf problems during or sometime after all that memory had been allocated and freed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This garbage collection pain is usually most poignantly felt when initializing very large immutable collections.&amp;nbsp; Without appropriate optimizations for this scenario, a large immutable collection will produce many times as much garbage during construction as its own final size in memory at completion.&amp;nbsp; So if you built a collection that requires 1MB of RAM just for the collection itself, you might have just blown through 4MB of RAM during its construction (freeing 3MB immediately after).&amp;nbsp; A well-written immutable collection class could optimize for this initialization case by allowing itself to reuse (i.e. mutate) tree nodes during initialization only, when such reuse could never be detectable outside as a &amp;ldquo;mutation&amp;rdquo;, which would solve the garbage generation problem for immutable collections, unless your collections tend to mutate very rapidly even after initial construction.&lt;/p&gt;
&lt;h4&gt;Summary&lt;/h4&gt;
&lt;table style="width: 483px;" border="0" cellspacing="0" cellpadding="2"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Read only&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Frozen&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Immutable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;&lt;strong&gt;Capabilities&lt;/strong&gt;&lt;/td&gt;
&lt;td width="116" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="97" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="131" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Thread-safe&lt;/td&gt;
&lt;td width="116" valign="top"&gt;No&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Yes&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Type-safe declaration&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Yes&lt;/td&gt;
&lt;td width="97" valign="top"&gt;TBD&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Immutable guarantee&lt;/td&gt;
&lt;td width="116" valign="top"&gt;No&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Yes&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Allows mutation&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Yes, shared&lt;/td&gt;
&lt;td width="97" valign="top"&gt;No&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Yes, isolated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;&lt;strong&gt;CPU&lt;/strong&gt;&lt;/td&gt;
&lt;td width="116" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="97" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="131" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Isolated mutations performance&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Poor&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Poor&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Great&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Shared mutation performance&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Great, except when underlying data structure is outgrown and must be cloned.&lt;/td&gt;
&lt;td width="97" valign="top"&gt;N/A.&amp;nbsp; No mutations allowed.&lt;/td&gt;
&lt;td width="131" valign="top"&gt;N/A. All mutations are isolated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td width="116" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="97" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td width="131" valign="top"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Storage data structure&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Array&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Array&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Binary tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Memory across isolated versions&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Full duplication&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Full duplication&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Efficient sharing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="137" valign="top"&gt;Garbage generation&lt;/td&gt;
&lt;td width="116" valign="top"&gt;Low&lt;/td&gt;
&lt;td width="97" valign="top"&gt;Low&lt;/td&gt;
&lt;td width="131" valign="top"&gt;Potentially high [&lt;a href="http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/30/immutable-collections-with-mutable-performance.aspx"&gt;update&lt;/a&gt;]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you enjoyed this post, you may enjoy &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/tags/immutability/"&gt;Eric Lippert&amp;rsquo;s blog posts tagged Immutability&lt;/a&gt;.&amp;nbsp; Eric Lippert wrote &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx"&gt;a good post on different kinds of immutability&lt;/a&gt; back in 2007.&lt;/p&gt;
&lt;p&gt;And please let me know if you found this post useful or interesting.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10198307" width="1" height="1"&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YEQH2HksZjQ:1YgDI7nFceY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=YEQH2HksZjQ:1YgDI7nFceY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YEQH2HksZjQ:1YgDI7nFceY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?i=YEQH2HksZjQ:1YgDI7nFceY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?a=YEQH2HksZjQ:1YgDI7nFceY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AndrewArnottMSDN?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewArnottMSDN/~4/YEQH2HksZjQ" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/andrewarnottms/archive/tags/Immutability/">Immutability</category><feedburner:origLink>http://blogs.msdn.com/b/andrewarnottms/archive/2011/08/22/read-only-frozen-and-immutable-types-and-collections.aspx</feedburner:origLink></item></channel></rss>
