<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" 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/"><channel><title>Jon Skeet: Coding Blog : Parallelisation, Benchmarking, Stack Overflow</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/Benchmarking/Stack+Overflow/default.aspx</link><description>Tags: Parallelisation, Benchmarking, Stack Overflow</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Revisiting randomness</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/04/revisiting-randomness.aspx</link><pubDate>Wed, 04 Nov 2009 07:40:15 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1737577</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1737577</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1737577</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/04/revisiting-randomness.aspx#comments</comments><description>&lt;p&gt;Almost every Stack Overflow question which includes the words &amp;quot;random&amp;quot; and &amp;quot;repeated&amp;quot; has the same basic answer. It&amp;#39;s one of the most common &amp;quot;gotchas&amp;quot; in .NET, Java, and no doubt other platforms: creating a new random number generator without specifying a seed will depend on the current instant of time. The current time as measured by the computer doesn&amp;#39;t change very often compared with how often you can create and use a random number generator – so code which repeatedly creates a new instance of Random and uses it once will end up showing a lot of repetition.&lt;/p&gt;  &lt;p&gt;One common solution is to use a static field to store a single instance of Random and reuse it. That&amp;#39;s okay in Java (where Random is thread-safe) but it&amp;#39;s not so good in .NET – if you use the same instance repeatedly from .NET, you can corrupt the internal data structures.&lt;/p&gt;  &lt;p&gt;A long time ago, I created a &lt;a href="http://pobox.com/~skeet/csharp/miscutil/usage/staticrandom.html"&gt;StaticRandom class&lt;/a&gt; in &lt;a href="http://pobox.com/~skeet/csharp/miscutil"&gt;MiscUtil&lt;/a&gt; – essentially, it was just a bunch of static methods (to mirror the instance methods found in Random) wrapping a single instance of Random and locking appropriately. This allows you to just call StaticRandom.Next(1, 7) to roll a die, for example. However, it has a couple of problems:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;It doesn&amp;#39;t scale well in a multi-threaded environment. When I originally wrote it, I benchmarked an alternative approach using [ThreadStatic] and at the time, locking won (at least on my computer, which may well have only had a single core). &lt;/li&gt;    &lt;li&gt;It doesn&amp;#39;t provide any way of getting at an instance of Random, other than by using new Random(StaticRandom.Next()). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The latter point is mostly a problem because it encourages a style of coding where you just use StaticRandom.Next(…) any time you want a random number. This is undoubtedly convenient in some situations, but it goes against the idea of &lt;a href="http://stackoverflow.com/questions/1667516/doesnt-passing-in-parameters-that-should-be-known-implicitly-violate-encapsulati/1667590#1667590"&gt;treating a source of randomness as a service or dependency&lt;/a&gt;. It makes it harder to get repeatability and to see what needs that dependency.&lt;/p&gt;  &lt;p&gt;I could have just added a method generating a new instance into the existing class, but I decided to play with a different approach – going back to per-thread instances, but this time using the &lt;a href="http://msdn.microsoft.com/en-us/library/dd642243(VS.100).aspx"&gt;ThreadLocal&amp;lt;T&amp;gt; class&lt;/a&gt; introduced in .NET 4.0. Here&amp;#39;s the resulting code:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Namespace"&gt;namespace&lt;/span&gt; RandomDemo     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Convenience class for dealing with randomness.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ThreadLocalRandom     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Random number generator used to generate seeds,&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// which are then used to create new random number&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// generators on a per-thread basis.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Random globalRandom = &lt;span class="Keyword"&gt;new&lt;/span&gt; Random();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; globalLock = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt;();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Random number generator &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; ThreadLocal&amp;lt;Random&amp;gt; threadRandom = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadLocal&amp;lt;Random&amp;gt;(NewRandom);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Creates a new instance of Random. The seed is derived &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// from a global (static) instance of Random, rather &lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// than time.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Random NewRandom()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;lock&lt;/span&gt; (globalLock)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; Random(globalRandom.Next());     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Returns an instance of Random which can be used freely&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// within the current thread.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Random Instance { get { &lt;span class="Statement"&gt;return&lt;/span&gt; threadRandom.Value; } }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next()&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next(int)&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next(&lt;span class="ValueType"&gt;int&lt;/span&gt; maxValue)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next(maxValue);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.Next(int, int)&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Next(&lt;span class="ValueType"&gt;int&lt;/span&gt; minValue, &lt;span class="ValueType"&gt;int&lt;/span&gt; maxValue)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.Next(minValue, maxValue);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.NextDouble()&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;double&lt;/span&gt; NextDouble()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; Instance.NextDouble();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;See &amp;lt;see cref=&amp;quot;Random.NextBytes(byte[])&amp;quot; /&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; NextBytes(&lt;span class="ValueType"&gt;byte&lt;/span&gt;[] buffer)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Instance.NextBytes(buffer);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The user can still call the static Next(…) methods if they want, but they can also get at the thread-local instance of Random by calling ThreadLocalRandom.Instance – or easily create a new instance with ThreadLocalRandom.NewRandom(). (The fact that NewRandom uses the global instance rather than the thread-local one is an implementation detail really; it happens to be convenient from the point of view of the ThreadLocal&amp;lt;T&amp;gt; constructor. It wouldn&amp;#39;t be terribly hard to change this.)&lt;/p&gt;  &lt;p&gt;Now it&amp;#39;s easy to write a method which needs randomness (e.g. to shuffle a deck of cards) and give it a Random parameter, then call it using the thread-local instance:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Shuffle(Random rng)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...     &lt;br /&gt;}     &lt;br /&gt;...     &lt;br /&gt;deck.Shuffle(ThreadLocalRandom.Instance); &lt;/div&gt;  &lt;p&gt;The Shuffle method is then easier to test and debug, and expresses its dependency explicitly.&lt;/p&gt;  &lt;h3&gt;Performance&lt;/h3&gt;  &lt;p&gt;I tested the &amp;quot;old&amp;quot; and &amp;quot;new&amp;quot; implementations in a very simple way – for varying numbers of threads, I called Next() a fixed number of times (from each thread) and timed how long it took for all the threads to finish. I&amp;#39;ve also tried a .NET-3.5-compatible version using ThreadStatic instead of ThreadLocal&amp;lt;T&amp;gt;, and running the original code and the ThreadStatic version on .NET 3.5 as well.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td align="right"&gt;Threads&lt;/td&gt;        &lt;td align="right"&gt;StaticRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;ThreadLocalRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;ThreadStaticRandom (4.0b2)&lt;/td&gt;        &lt;td align="right"&gt;StaticRandom(3.5)&lt;/td&gt;        &lt;td align="right"&gt;ThreadStaticRandom (3.5)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;1&lt;/td&gt;        &lt;td align="right"&gt;11582&lt;/td&gt;        &lt;td align="right"&gt;6016&lt;/td&gt;        &lt;td align="right"&gt;10150&lt;/td&gt;        &lt;td align="right"&gt;10373&lt;/td&gt;        &lt;td align="right"&gt;16049&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;2&lt;/td&gt;        &lt;td align="right"&gt;24667&lt;/td&gt;        &lt;td align="right"&gt;7214&lt;/td&gt;        &lt;td align="right"&gt;9043&lt;/td&gt;        &lt;td align="right"&gt;25062&lt;/td&gt;        &lt;td align="right"&gt;17257&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;3&lt;/td&gt;        &lt;td align="right"&gt;38095&lt;/td&gt;        &lt;td align="right"&gt;10295&lt;/td&gt;        &lt;td align="right"&gt;14771&lt;/td&gt;        &lt;td align="right"&gt;36827&lt;/td&gt;        &lt;td align="right"&gt;25625&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td align="right"&gt;4&lt;/td&gt;        &lt;td align="right"&gt;49402&lt;/td&gt;        &lt;td align="right"&gt;13435&lt;/td&gt;        &lt;td align="right"&gt;19116&lt;/td&gt;        &lt;td align="right"&gt;47882&lt;/td&gt;        &lt;td align="right"&gt;34415&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;A few things to take away from this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The numbers were slightly erratic; somehow it was quicker to do twice the work with ThreadStaticRandom on .NET 4.0b2! This isn&amp;#39;t the perfect benchmarking machine; we&amp;#39;re interested in trends rather than absolute figures. &lt;/li&gt;    &lt;li&gt;Locking hasn&amp;#39;t changed much in performance between framework versions &lt;/li&gt;    &lt;li&gt;ThreadStatic has improved &lt;em&gt;massively&lt;/em&gt; between .NET 3.5 and 4.0 &lt;/li&gt;    &lt;li&gt;Even on 3.5, ThreadStatic wins over a global lock as soon as there&amp;#39;s contention &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The only downside to the ThreadLocal&amp;lt;T&amp;gt; version is that it requires .NET 4.0 - but the ThreadStatic version works pretty well too.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s worth bearing in mind that of course this is testing the highly unusual situation where there&amp;#39;s a &lt;em&gt;lot&lt;/em&gt; of contention in the global lock version. The performance difference in the single-threaded version where the lock is always uncontended is still present, but very small.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;After reading the comments and thinking further, I would indeed get rid of the static methods elsewhere. Also, for the purposes of dependency injection, I agree that it&amp;#39;s a good idea to have a factory interface &lt;em&gt;where that&amp;#39;s not overkill&lt;/em&gt;. The factory implementation could use either the ThreadLocal or ThreadStatic implementations, or effectively use the global lock version (by having its own instance of Random and a lock). In many cases I&amp;#39;d regard that as overkill, however.&lt;/p&gt;  &lt;p&gt;One other interesting option would be to create a thread-safe instance of Random to start with, which delegated to thread-local &amp;quot;normal&amp;quot; implementations. That would be very useful from a DI standpoint.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1737577" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category></item></channel></rss>