{"id":36050,"date":"2013-01-07T06:19:22","date_gmt":"2013-01-07T06:19:22","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/andrewarnottms\/2013\/01\/07\/immutable-collection-algorithmic-complexity\/"},"modified":"2019-04-03T21:33:36","modified_gmt":"2019-04-04T04:33:36","slug":"immutable-collection-algorithmic-complexity","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/immutable-collection-algorithmic-complexity\/","title":{"rendered":"Immutable collection algorithmic complexity"},"content":{"rendered":"<p>I received some feedback from <a href=\"http:\/\/blogs.msdn.com\/b\/bclteam\/archive\/2012\/12\/18\/preview-of-immutable-collections-released-on-nuget.aspx\" target=\"_blank\">my recent BCL blog post on the prerelease of the immutable collections<\/a> 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):<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<th>         &nbsp;<\/p>\n<\/th>\n<th>\n<p>Mutable (amortized)<\/p>\n<\/th>\n<th>\n<p>Mutable (worst case)<\/p>\n<\/th>\n<th>\n<p>Immutable<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p>Stack.Push<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Queue.Enqueue<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>List.Add<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>List lookup by index<\/td>\n<td>O(1)<\/td>\n<td>O(1)<\/td>\n<td>O(log n)<\/td>\n<\/tr>\n<tr>\n<td>List enumeration<\/td>\n<td>O(n)<\/td>\n<td>O(n)<\/td>\n<td>O(n)<\/td>\n<\/tr>\n<tr>\n<td>\n<p>HashSet.Add, lookup<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SortedSet.Add<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Dictionary.Add<\/p>\n<\/td>\n<td>\n<p>O(1)<\/p>\n<\/td>\n<td>\n<p>O(n)<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>Dictionary lookup<\/td>\n<td>O(1)<\/td>\n<td>O(1) &ndash; or strictly O(n)<\/td>\n<td>O(log n)<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SortedDictionary.Add<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<td>\n<p>O(n log n)<\/p>\n<\/td>\n<td>\n<p>O(log n)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A noteworthy trait to call out here is that where a List&lt;T&gt; can be efficiently enumerated using either a <strong>for <\/strong>loop or a <strong>foreach <\/strong>loop, ImmutableList&lt;T&gt; does a poor job inside a <strong>for<\/strong> loop, due to its O(log n) time for its indexer. It does fine when using <strong>foreach<\/strong> however. This is because ImmutableList&lt;T&gt; uses a binary tree to store its data instead of a simple array like List&lt;T&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.<\/p>\n<p>Another point to call out from the above table is that SortedSet&lt;T&gt; has the <em>same<\/em> complexity as ImmutableSortedSet&lt;T&gt;, and in fact in perf tests they show up as pretty close. That&rsquo;s because they both use binary trees. The significant difference of course is that ImmutableSortedSet&lt;T&gt; uses an immutable one. Since ImmutableSortedSet&lt;T&gt; also offers a Builder class that allows mutation, you <em>can<\/em> have your immutability and performance too. Woot.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I received some feedback from my recent BCL blog post on the prerelease of the immutable collections 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): &nbsp; Mutable (amortized) Mutable (worst case) Immutable Stack.Push O(1) O(n) [&hellip;]<\/p>\n","protected":false},"author":2685,"featured_media":37840,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[106,4617,3916],"class_list":["post-36050","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-permierdev","tag-net","tag-andarno","tag-immutability"],"acf":[],"blog_post_summary":"<p>I received some feedback from my recent BCL blog post on the prerelease of the immutable collections 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): &nbsp; Mutable (amortized) Mutable (worst case) Immutable Stack.Push O(1) O(n) [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36050","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/2685"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=36050"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/36050\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/37840"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=36050"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=36050"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=36050"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}