{"id":92851,"date":"2016-01-14T07:00:00","date_gmt":"2016-01-14T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=92851"},"modified":"2019-03-13T12:10:21","modified_gmt":"2019-03-13T19:10:21","slug":"20160114-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160114-00\/?p=92851","title":{"rendered":"When you start talking about numbers as small as 2\u207b\u00b9\u00b2\u00b2, you have to start looking more closely at the things you thought were zero"},"content":{"rendered":"<p>GUID generation algorithm 4 fills the GUID with 122 random bits. The odds of two GUIDs colliding are therefore one in 2&sup1;&sup2;&sup2;, which is a phenomenally small number. When you are dealing with rates this low, you have to adjust your frame of reference. <\/p>\n<p>Some people don&#8217;t like algorithm 4 because the algorithm is not designed to ensure uniqueness. There is a chance, admittedly small, that a collision will occur. On the other hand, algorithm 1, for example, uses time-space coordinates to ensure <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150410-00\/?p=44263#comment-1184493\">zero chance of duplication, unless someone screws up the generation process<\/a>. <\/p>\n<p>Hang on a second. &#8220;Unless someone screws up the generation process.&#8221; Ah, so it&#8217;s not zero after all, because there is of course a tiny chance that something will get screwed up in the generation process. <\/p>\n<p>According to <a HREF=\"http:\/\/www.cs.toronto.edu\/~bianca\/papers\/sigmetrics09.pdf\">this research paper (pdf)<\/a>, memory chips suffer 25,000 to 70,000 errors per billion hours per megabit. Let&#8217;s do some back-of-the-envelope calculations. <\/p>\n<table BORDER=\"0\" STYLE=\"text-align: center\">\n<tr>\n<td>    25,000 to 70,000 errors     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    10&#x2079; hours &times; 2&sup2;&#x2070; bits     <\/td>\n<td>    &nbsp;&#x2248;&nbsp;     <\/td>\n<td>    2&sup1;&#x2075; errors     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    2&sup3;&#x2070; hours &times; 2&sup2;&#x2070; bits     <\/td>\n<td>    &nbsp;=&nbsp;     <\/td>\n<td>    1 error     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    2&sup3;&#x2075; hours &times; bits     <\/td>\n<\/table>\n<p>Now let&#8217;s see how this error rate converts to &#8220;corrupted GUIDs&#8221;. <\/p>\n<table BORDER=\"0\" STYLE=\"text-align: center\">\n<tr>\n<td>    1 error     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    2&sup3;&#x2075; hours &times; bits     <\/td>\n<td>    &nbsp;&times;&nbsp;     <\/td>\n<td>    2&#x2077; bits     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    1 GUID     <\/td>\n<td>    &nbsp;&times;&nbsp;     <\/td>\n<td>    1 hour     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    60 &times; 60 &times; 10&#x2079; nanoseconds     <\/td>\n<\/table>\n<p>Now, 60 &times; 60 = 3600 is approximately 4096 = 2&sup1;&sup2;, and 10&#x2079; is approximately 2&sup3;&#x2070;. <\/p>\n<table BORDER=\"0\" STYLE=\"text-align: center\">\n<td>    &#x2248;&nbsp;     <\/td>\n<td>    2&#x2077; errors     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    2&sup3;&#x2075; &times; 2&sup1;&sup2;     &times; 2&sup3;&#x2070; GUID &times; nanosecond     <\/td>\n<td>    &nbsp;=&nbsp;     <\/td>\n<td>    1 errors     <\/p>\n<hr STYLE=\"border-color: inherit;color: black;background-color: black\">    2&#x2077;&#x2070; GUID &times; nanosecond     <\/td>\n<\/table>\n<p>The odds that a GUID will be corrupted in memory in the one nanosecond between the time it is created and the time the value is copied somewhere safe is therefore around one in 2&#x2077;&#x2070;. <\/p>\n<p>This is 2&#x2075;&sup2; &#x2248; 10&sup1;&#x2075; = a quadrillion* times more likely than a collision between two GUIDs generated by algorithm 4. <\/p>\n<p>And that&#8217;s just mechanical failures in the RAM chips. There are other ways that the generation process can get screwed up. For example, there could be a failure in the CPU itself, maybe due to overheating or <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20050412-47\/?p=35923\">overclocking<\/a>. Or a bit error on the hard drive. Or <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20091001-00\/?p=16533\">a programming error<\/a>. <\/p>\n<p>When you start talking about numbers as small as 2&#x207b;&sup1;&sup2;&sup2;, you have to start looking more closely at all the things that you thought were zero. <\/p>\n<p>* Or &#8220;a thousand billion&#8221; if you use the European scale. <\/p>\n<p><b>Bonus chatter<\/b>: Note that I&#8217;m not saying that a collision caused by a random bit flip is more likely than a collision caused by a v4 GUID happening to match some other v4 GUID. I&#8217;m saying that it&#8217;s wrong to say that the v1 GUID generator will never generate a collision, because there&#8217;s a nonzero probability that the v1 GUID generator will deviate from the algorithm. Sure, that probably may be minuscule, but when you&#8217;re dealing with numbers like 2&#x207b;&sup1;&sup2;&sup2;, these minuscule probabilities become significant. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Do the math.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-92851","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Do the math.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=92851"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92851\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=92851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=92851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=92851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}