<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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/" version="2.0"><channel><title>All Your Base Are Belong To Us</title><link>http://blogs.microsoft.co.il/blogs/sasha/</link><description>Mostly .NET internals and other kinds of gory details</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/sashag" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="sashag" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>DevAcademy4 Session: Parallel Programming in .NET 4 and Visual Studio 2010</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/03/20/devacademy4-session-parallel-programming-in-net-4-and-visual-studio-2010.aspx</link><pubDate>Sat, 20 Mar 2010 07:43:19 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:552362</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=552362</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/03/20/devacademy4-session-parallel-programming-in-net-4-and-visual-studio-2010.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/DevAcademy4Logo_1EECDDEB.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;margin:0px 0px 10px 10px;display:inline;border-top:0px;border-right:0px;" title="DevAcademy4Logo" border="0" alt="DevAcademy4Logo" align="right" src="http://blogs.microsoft.co.il/blogs/sasha/DevAcademy4Logo_thumb_14D83CC0.png" width="177" height="240" /&gt;&lt;/a&gt;Sorry for the late announcement, but on Monday I’m going to present a session called Parallel Programming in .NET 4 and Visual Studio 2010 at the &lt;a href="http://www.microsoft.com/israel/msdn/devacademy4/"&gt;Microsoft Developer Academy 4&lt;/a&gt; (Avenue, Airport City).&lt;/p&gt;  &lt;p&gt;There are six (!) Sela speakers at the conference: Gil Fink, Alex Golesh, Shai Raiten, Alon Fliess, Noam King, and yours truly—and I’m sure they are going to rock, so take a look at the conference schedule to see which sessions you want to attend.&lt;/p&gt;  &lt;p&gt;I wouldn’t want to ruin the fun for the ones who are planning to come to my talk, but here are some of the things we’ll see:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Styles of concurrent applications today&lt;/li&gt;    &lt;li&gt;The shift from imperative to declarative parallelism&lt;/li&gt;    &lt;li&gt;What’s in the box with .NET 4 and Visual Studio 2010 with regards to parallel programming&lt;/li&gt;    &lt;li&gt;Data parallelism, processing parallelism, explicit task management&lt;/li&gt;    &lt;li&gt;Migration strategy and integration examples&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The sessions will be recorded (AFAIK) so even if you’re unable to attend my talk, I’ll let you know how you can tune in after the conference. I will also upload the presentation, the demos, and any other materials after my talk.&lt;/p&gt;  &lt;p&gt;As for the demos—let’s just say that it’s popular to integrate Twitter into every demo at every conference talk, so there will be a Twitter client of some sort but it might have a surprising user interface.&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;/--------------------\     &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;&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;&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;&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;&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;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; |      &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; |      &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; |      &lt;br /&gt;|&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; |      &lt;br /&gt;|&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; |      &lt;br /&gt;|&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;|&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;&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;&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;&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |      &lt;br /&gt;\--------------------/&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=552362" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/Phi0YfasY94" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/ParallelFX/default.aspx">ParallelFX</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/DevAcademy4/default.aspx">DevAcademy4</category></item><item><title>Are We Training Our Customers to Be Dumb?</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/16/are-we-training-our-customers-to-be-dumb.aspx</link><pubDate>Tue, 16 Feb 2010 20:29:28 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:520233</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=520233</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/16/are-we-training-our-customers-to-be-dumb.aspx#comments</comments><description>&lt;p&gt;During the past few years at Sela, I’ve authored several courses and participated in the development process of several dozens more. They covered a great deal of topics – ranging from the gory inner workings of Windows and the CLR, through new technologies like LINQ and Windows 7, and all the way to introductory courses to C# programming. I’ve also had the experience of designing and developing courses in a variety of styles – the “Sela style”, which focuses on the brilliance of the instructor delivering the course and slightly deemphasizes the minute details in student handbooks, the “standard international courseware style”, which is all about attention to detail and greatly elaborate lab instructions, and some combinations of the two.&lt;/p&gt;  &lt;p&gt;I always preferred concise exercises and labs that emphasize the student’s ability to think and process the material, over exercises that involve straightforward typing or copy-pasting code from the lab manual into Visual Studio and seeing it compile. And I always wondered if it was just some mentality thing here in Israel, or a personal preference I have because I like teaching difficult courses to an audience of highly experienced developers. I also wondered if the reason some customers prefer and training companies encourage the drill-down, copy-paste labs was a matter of dumbing down the lab and making sure everyone in the classroom is capable of finishing it within the allotted time; not to mention that a short and concise lab definition might seem vague and lacking in detail to some audiences.&lt;/p&gt;  &lt;p&gt;But one thing just occurred to me. Take a look at this exercise from an introductory mathematical analysis course, one of the first things I found by looking up “mathematical analysis homework” on Google:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Let &lt;em&gt;f&lt;/em&gt; be a monotone function on an interval. Prove that &lt;em&gt;f&lt;/em&gt; is continuous iff its image is an interval.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Can you see what I’m getting at? OK, here’s an example of an exercise I used a few weeks ago when teaching a concurrent programming course:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The reader-writer lock design shown in class uses two mutexes and an event.&amp;#160; Convert this design to use &lt;i&gt;only&lt;/i&gt; a single semaphore. Prove that there is a possible deadlock if multiple writers attempt to acquire the lock. Fix the problem by introducing a mutex (additionally to the semaphore).&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Compare and contrast to this hypothetical example from today’s typical software industry “courseware”:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In this task, you will implement the &lt;em&gt;IComparable&lt;/em&gt; interface so that instances of your class can be sorted by external sort algorithms. Open the &lt;em&gt;MyClass.cs&lt;/em&gt; file in Visual Studio, and navigate to the &lt;em&gt;MyClass&lt;/em&gt; class definition. (To open a file, click File –&amp;gt; Open.)&lt;/p&gt;    &lt;p&gt;Declare that your class is implementing the &lt;em&gt;IComparable&lt;/em&gt; interface using the interface implementation syntax, as follows:&lt;/p&gt;    &lt;p&gt;&lt;em&gt;internal class MyClass : IComparable {&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;Implement the &lt;em&gt;CompareTo&lt;/em&gt; method. To compare the parameter to your object, cast the parameter to an instance of &lt;em&gt;MyClass&lt;/em&gt;. Next, compare the values of the &lt;em&gt;X&lt;/em&gt; and &lt;em&gt;Y&lt;/em&gt; properties of the parameter to the values of the &lt;em&gt;X&lt;/em&gt; and &lt;em&gt;Y&lt;/em&gt; properties of your instance (&lt;em&gt;this&lt;/em&gt;).&lt;/p&gt;    &lt;p&gt;[…several pages later…]&lt;/p&gt;    &lt;p&gt;Congratulations! In this exercise, you have implemented the &lt;em&gt;IComparable&lt;/em&gt; interface so that users of your class can compare instances of it without being aware of your class’ implementation details. For more information about the &lt;em&gt;IComparable&lt;/em&gt; interface, consult the MSDN documentation at […]&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s mind-numbing to read just &lt;em&gt;this &lt;/em&gt;passage, not to mention the 30+ pages of standardized jargon it is usually surrounded by. Are we deliberately dumbing down our training materials and by extension the developer community? What’s the ultimate objective of having every step of the way explained in excruciating detail? How is it possible to learn anything without even trying to perform the task on your own before copy-pasting code from the student manual?&lt;/p&gt;  &lt;p&gt;I’ve officially given up trying to understand this phenomenon. But I do know this: Given the choice between short and concise instructions and a 30+ page lab document, I would choose the former over the latter even if it were a million times harder.&lt;/p&gt;  &lt;p&gt;I feel that a good litmus test for a properly designed lab exercise would be the following relation:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Lines of Text in Lab Manual / Lines of Code Written by Student &amp;lt; 0.1&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=520233" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/p9N3vHdp0r0" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Teaching/default.aspx">Teaching</category></item><item><title>Another Happy User of Windows Home Server</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/04/another-happy-user-of-windows-home-server.aspx</link><pubDate>Thu, 04 Feb 2010 16:59:43 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:514180</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>8</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=514180</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/04/another-happy-user-of-windows-home-server.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" border="0" align="right" src="http://neo.nextechnews.com/wp-content/uploads/2009/12/825c6fa667erver2.jpg.jpg" width="280" height="234" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;A couple of months ago I bought an &lt;a href="http://usingwindowshomeserver.com/2009/05/24/in-depth-review-of-the-acer-aspire-easystore-h340-windows-home-server/"&gt;Acer Aspire easyStore&lt;/a&gt; home server for my home. It comes preinstalled with Windows Home Server. The configuration I bought has a single 1TB hard drive with the OS itself and plenty of room for backups and data; I also ordered another internal WD Caviar Green 1.5TB hard drive and an external 2TB Seagate hard drive.&lt;/p&gt;  &lt;p&gt;The internal hard drive was faulty from the start, so I’m in the process of replacing it, but right now I’m working with 3TB of space, which is enough for my backups and most of my data. It’s really easy to add or remove drives, and you can do it without ever shutting down the server by simply opening the front door, removing one of the bays, inserting your hard drive (screw-less design – another bonus!) and you’re good to go.&lt;/p&gt;  &lt;p&gt;One of the neatest things about this server is its form factor – it’s really small. I have a small storage cabinet that’s 30cm (1’) wide and about 70cm (2’4”) tall, and it hosts the home server, the cable modem, the router and the external hard drive without missing a beat.&lt;/p&gt;  &lt;p&gt;If you know me personally, you probably know that I’m the (grumpy) system administrator for seven computers (two desktops, two media centers and three laptops), and ensuring the integrity of the data, performing timely backups, restoring them after installation problems and so on – can quickly become annoying if it’s not your day job… One of the primary objectives of buying the server was to stop worrying!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_2308587E.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;margin:0px 0px 0px 10px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" align="right" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_5286ED17.png" width="303" height="213" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So far I’m very happy with my home server. I’m using it for backups – and because I have Windows 7 on all seven machines, there’s plenty of duplication which Windows Home Server detects – that’s why it’s currently using only 424GB of space for backups. I’m using it for shared storage – photos, videos, music and software installations. The one thing I’m not storing on the home server yet is recorded TV, because it usually doesn’t survive more than a couple of days before being deleted, and my media center’s 1.5TB of storage are more than enough to store plenty of recorded programs.&lt;/p&gt;  &lt;p&gt;I’m also using the home server to remotely connect to my computers at home. When you buy a Windows Home Server, you’re automatically entitled to a sub-domain (under .homeserver.com, or other alternatives) that you can use to connect to your server. You can browse all the shared folders and remotely connect to any computer at home using Remote Desktop.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_09B07B11.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_6E3B9EDA.png" width="524" height="314" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I look back at the last few years and realize that I’ve never been very good with backups. I have backups of the most important personal stuff on DVDs, and some of the work stuff is safely backed up by &lt;a href="http://www.mesh.com"&gt;LiveMesh&lt;/a&gt; and &lt;a href="http://skydrive.live.com"&gt;SkyDrive&lt;/a&gt;. However, if one of my PCs at home suffered a major breakdown, it would take me &lt;em&gt;weeks&lt;/em&gt; to restore it to a decent state. With Windows Home Server, restoring over a wireless N connection or a wired Gigabit connection is a matter of hours at most.&lt;/p&gt;  &lt;p&gt;This definitely isn’t the freshest piece of advice you’ve ever heard, but if you’re not thinking about backups, it’s better to start sooner than later, and Windows Home Server is a good place to start :-)&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=514180" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/xdUkCJIvJxk" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/HomeServer/default.aspx">HomeServer</category></item><item><title>Race Condition When Modifying the HttpRequestMessageProperty in an Outgoing WCF Message</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/03/race-condition-when-modifying-the-httprequestmessageproperty-in-an-outgoing-wcf-message.aspx</link><pubDate>Wed, 03 Feb 2010 15:22:25 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:513785</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=513785</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/02/03/race-condition-when-modifying-the-httprequestmessageproperty-in-an-outgoing-wcf-message.aspx#comments</comments><description>&lt;p&gt;I’ve stumbled upon a fairly obscure race condition in WCF’s implementation of the HTTP transport, and just wanted to quickly share it with you should you ever encounter it.&lt;/p&gt;  &lt;p&gt;I was using a simple publish/subscribe router similar to &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2008/03/15/wcf-router-and-publish-subscribe-sample-implementation.aspx"&gt;the one I’ve blogged about two years ago&lt;/a&gt; to automatically publish notifications to a list of subscribers. The router is a WCF service that implements a generic interface that takes a &lt;em&gt;Message&lt;/em&gt; and creates multiple copies of it to send to all registered subscribers.&lt;/p&gt;  &lt;p&gt;Here’s my original take on the dispatch code: [exception-handling removed for clarity]&lt;/p&gt;   &lt;div style="font-family:consolas;background:white;color:black;font-size:11pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;string&lt;/span&gt; subscriber &lt;span style="color:blue;"&gt;in&lt;/span&gt; subscribers)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Message&lt;/span&gt; toSend = buffer.CreateMessage();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt; proxy =       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt;&amp;gt;.CreateChannel(&lt;/p&gt;    &lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;Program&lt;/span&gt;.Binding, &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EndpointAddress&lt;/span&gt;(subscriber));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; proxy.Action(toSend);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; ((&lt;span style="color:#2b91af;"&gt;ICommunicationObject&lt;/span&gt;)proxy).Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; toSend.Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;…now, seeing that the messages are copied and the send operation is stateless, there’s no reason why I shouldn’t be able to &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2009/09/05/parallel-programming-in-visual-studio-2010-msdn-event-deck-and-demos.aspx"&gt;parallelize&lt;/a&gt; these operations and make sure subscribers get the notification messages more promptly:&lt;/p&gt;   &lt;div style="font-family:consolas;background:white;color:black;font-size:11pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;Parallel&lt;/span&gt;.ForEach(&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; subscribers,&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; subscriber =&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Message&lt;/span&gt; toSend = buffer.CreateMessage();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt; proxy =       &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; &lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt;&amp;gt;.CreateChannel(&lt;/p&gt;    &lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;Program&lt;/span&gt;.Binding, &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EndpointAddress&lt;/span&gt;(subscriber));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; proxy.Action(toSend);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ((&lt;span style="color:#2b91af;"&gt;ICommunicationObject&lt;/span&gt;) proxy).Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; toSend.Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;But unfortunately, the latter version of the code fails with the following exception, that only occurs once in several hundreds of messages on my machine: [removed parameters from stack trace for clarity]&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;System.NullReferenceException: Object reference not set to an instance of an object. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Server stack trace:      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpRequestMessageProperty.get_Headers()       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.PrepareHttpSend…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpOutput.Send…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.SendRequest…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.RequestChannel.Request…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Dispatcher.RequestChannelBinder.Send…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannel.Call…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService…       &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.Invoke…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Exception rethrown at [0]:      &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage…       &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke…       &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.IGenericOneWayContract.Action…       &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.PubSubRouter.&amp;lt;&amp;gt;c__DisplayClass1.&amp;lt;Action&amp;gt;b__0…       &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.Parallel.&amp;lt;&amp;gt;c__DisplayClass3`1.&amp;lt;ForEach&amp;gt;b__0…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;After looking at the code with Reflector, it seems that during the &lt;em&gt;PrepareHttpSend&lt;/em&gt; method that we see in the stack trace, there’s a phase where the message properties (including the &lt;em&gt;HttpRequestMessageProperty&lt;/em&gt;) are refreshed, e.g. with HTTP header information. Why, however, should there be a problem with the parallel version of the code if I’m delivering separate copies of the message to my subscribers?&lt;/p&gt;  &lt;p&gt;Well, from looking at the implementation of message cloning with Reflector, it appears that message properties are not cloned unless they implement the &lt;em&gt;IMessageProperty&lt;/em&gt; interface (see &lt;em&gt;MessageProperties.CreateCopyOfPropertyValue&lt;/em&gt;). The &lt;em&gt;HttpRequestMessageProperty&lt;/em&gt; class does not implement this interface, and therefore “cloning” it consists of simply returning the original value.&lt;/p&gt;  &lt;p&gt;Now the problem should be evident – we have multiple threads that are trying to modify the same &lt;em&gt;HttpRequestMessageProperty &lt;/em&gt;instance, with its HTTP header collection and whatnot. There’s a fairly rare race condition because most of the time the operations on the HTTP headers don’t collide, and happen to leave the message property in a consistent state. When they do collide, we get the above exception.&lt;/p&gt;  &lt;p&gt;There’s actually another variety of this problem that I’ve seen in the wild, but haven’t been able to reproduce on my machine – it’s when the message is eventually sent, but contains duplicate HTTP headers! This is obviously rather difficult to diagnose because the message is successfully sent with the duplicate headers but the subscriber refuses to receive it! The same fix was sufficient for both of the issues.&lt;/p&gt;  &lt;p&gt;So, what’s the fix? In this case, short of writing a manual serialization mechanism for message properties, I didn’t see many options other than a workaround. The workaround I found is to remove the &lt;em&gt;HttpRequestMessageProperty&lt;/em&gt; from the message before creating copies – this will cause the transport channel (&lt;em&gt;HttpOutput&lt;/em&gt;) to create a new instance of the property and attach this fresh copy to the message.&lt;/p&gt;  &lt;p&gt;In other words, the complete and working version of the code is something along the following lines:&lt;/p&gt;   &lt;div style="font-family:consolas;background:white;color:black;font-size:11pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;strong&gt;message.Properties.Remove(&lt;span style="color:#2b91af;"&gt;HttpRequestMessageProperty&lt;/span&gt;.Name);&lt;/strong&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;MessageBuffer&lt;/span&gt; buffer = message.CreateBufferedCopy(&lt;span style="color:blue;"&gt;int&lt;/span&gt;.MaxValue);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] subscribers = …;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:#2b91af;"&gt;Parallel&lt;/span&gt;.ForEach(&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; subscribers,&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; subscriber =&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Message&lt;/span&gt; toSend = buffer.CreateMessage();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt; proxy =&lt;/p&gt;    &lt;p style="margin:0px;"&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; &lt;span style="color:#2b91af;"&gt;ChannelFactory&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IGenericOneWayContract&lt;/span&gt;&amp;gt;.CreateChannel(&lt;/p&gt;    &lt;p style="margin:0px;"&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 style="color:#2b91af;"&gt;Program&lt;/span&gt;.Binding, &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EndpointAddress&lt;/span&gt;(subscriber));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; proxy.Action(toSend);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ((&lt;span style="color:#2b91af;"&gt;ICommunicationObject&lt;/span&gt;) proxy).Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; toSend.Close();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;buffer.Close();&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;I thought it would be interesting to test this behavior with WCF 4.0. On Visual Studio 2010 Beta 2, I was able to reproduce the duplicate HTTP headers problem, with the following exception, although the problem is admittedly rare: [again, edited for clarity; I marked the duplicate header in &lt;em&gt;italic&lt;/em&gt;]&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;System.ServiceModel.ProtocolException: Content Type &lt;em&gt;application/soap+xml; charset=utf-8,application/soap+xml; charset=utf-8&lt;/em&gt; was not supported by service &lt;/font&gt;&lt;font face="CONSOLAS"&gt;http://&lt;/font&gt;&lt;font face="CONSOLAS"&gt;localhost:8993/Client_6.&amp;#160; The client and service bindings may be mismatched. ---&amp;gt; System.Net.WebException: The remote server returned an error: (415) Cannot process the message because the content type &amp;#39;application/soap+xml; charset=utf-8,application/soap+xml; charset=utf-8&amp;#39; was not the expected type &amp;#39;application/soap+xml; charset=utf-8&amp;#39;..     &lt;br /&gt;&amp;#160;&amp;#160; at System.Net.HttpWebRequest.GetResponse…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply…      &lt;br /&gt;&amp;#160;&amp;#160; --- End of inner exception stack trace --- &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Server stack trace:     &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply…&amp;#160;&amp;#160; at System.ServiceModel.Channels.RequestChannel.Request…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Dispatcher.RequestChannelBinder.Send…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannel.Call…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.Invoke… &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Exception rethrown at [0]:     &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.IGenericOneWayContract.Action…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.PubSubRouter.&amp;lt;&amp;gt;c__DisplayClass2.&amp;lt;Action&amp;gt;b__1…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.Parallel.&amp;lt;&amp;gt;c__DisplayClass4`1.&amp;lt;ForEach&amp;gt;b__1…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Finally, in another test run I encountered a third variety of this exception, that I wasn’t able to see with WCF 3.0. It’s due to an internal implementation change, but the underlying problem is still the same race condition as before: [edited for clarity]&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;System.ArgumentException: Item has already been added. Key in dictionary: &amp;#39;Content-Type&amp;#39;&amp;#160; Key being added: &amp;#39;Content-Type&amp;#39; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Server stack trace:     &lt;br /&gt;&amp;#160;&amp;#160; at System.Collections.Hashtable.Insert…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Collections.Hashtable.Add…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Collections.Specialized.NameObjectCollectionBase.BaseAdd…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Collections.Specialized.NameValueCollection.Add…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Net.WebHeaderCollection.Add…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Collections.Specialized.NameValueCollection.Add…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpRequestContext.ListenerHttpContext.System.ServiceModel.Channels.HttpRequestMessageProperty.IHttpHeaderProvider.CopyHeaders…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpRequestMessageProperty.get_Headers…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.PrepareHttpSend…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpOutput.Send…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.SendRequest…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.RequestChannel.Request…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Dispatcher.RequestChannelBinder.Send…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannel.Call…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService…      &lt;br /&gt;&amp;#160;&amp;#160; at System.ServiceModel.Channels.ServiceChannelProxy.Invoke… &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;Exception rethrown at [0]:     &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage…      &lt;br /&gt;&amp;#160;&amp;#160; at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.IGenericOneWayContract.Action…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.PubSubRouter.&amp;lt;&amp;gt;c__DisplayClass2.&amp;lt;Action&amp;gt;b__1…      &lt;br /&gt;&amp;#160;&amp;#160; at WCFHttpMessageProperties.Parallel.&amp;lt;&amp;gt;c__DisplayClass4`1.&amp;lt;ForEach&amp;gt;b__1…&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This last exception even seems to hint that someone at Microsoft introduced an additional sanity check so that messages with duplicate headers do not even leave the HTTP transport, but this sanity check doesn’t work (see the previous exception) and doesn’t fix the root cause of this issue, which is the fact that WCF message properties are not properly cloned when the message is cloned.&lt;/p&gt;  &lt;p&gt;Fortunately, the same workaround fixes the problem in WCF 4.0 a well.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=513785" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/xDqEPfbSwKQ" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/WCF/default.aspx">WCF</category></item><item><title>IsBadXxxPtr Is Really Harmful – Please Don’t Use These Functions</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/15/isbadxxxptr-is-really-harmful-please-don-t-use-these-functions.aspx</link><pubDate>Fri, 15 Jan 2010 17:21:36 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:498663</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=498663</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/15/isbadxxxptr-is-really-harmful-please-don-t-use-these-functions.aspx#comments</comments><description>&lt;p&gt;You might have stumbled upon posts like &lt;a href="http://beta.blogs.microsoft.co.il/blogs/asafshelly/archive/2009/12/27/verifying-c-buffers.aspx"&gt;this one&lt;/a&gt; that tell you there’s a simple solution for verifying that a memory location is OK for read/write/execution: Just use the “IsBadXxxPtr” family of functions that take a memory address and return a &lt;em&gt;BOOL&lt;/em&gt; indicating if you can use the memory.&lt;/p&gt;  &lt;p&gt;It turns out (and I’m &lt;a href="http://blogs.msdn.com/larryosterman/archive/2004/05/18/134471.aspx"&gt;hardly&lt;/a&gt; &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx"&gt;the first&lt;/a&gt; to blog about it) that calling these functions causes more problems than it solves, and causes bugs rather than fixes them. Please heed the collective advice and stay away from these APIs.&lt;/p&gt;  &lt;p&gt;Here are some reasons why:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Non-atomicity&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you want to test a page for reading, a standard approach would be to call &lt;a href="http://msdn.microsoft.com/en-us/library/aa909024.aspx"&gt;IsBadReadPtr&lt;/a&gt;, get a &lt;em&gt;FALSE&lt;/em&gt; result and then try reading from the page, right? Well, what stops some other thread (or even your thread in an APC, for example) from unmapping that page and rendering it invalid for reading just after your checked but before you had a chance to read from it? Guess what, you crash – and this time you crash in a very surprising location. If you try debugging, you’ll see that your app causes a read access violation after testing the address with &lt;em&gt;IsBadReadPtr&lt;/em&gt;, and head-scratching is guaranteed.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Corrupt memory if possible”&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb202773.aspx"&gt;IsBadWritePtr&lt;/a&gt; is even worse. As Raymond Chen aptly put it, this method should really be called &lt;em&gt;CorruptMemoryIfPossible&lt;/em&gt;. What this method does is try to write a single byte to the beginning of every page in the range that you passed to it, and then fix up the old value of that byte if the write succeeded.&lt;/p&gt;  &lt;p&gt;Two horrible things come to mind: First, another thread can observe the changed byte before the API had a change to fix it up to the old value. This is clearly very bad. Another horrible thing (which is far less likely though) is that the page becomes read-only after the test byte has been written and before the API had a chance to fix it to the old value. Both of these things are &lt;a href="http://support.microsoft.com/default.aspx/kb/960154"&gt;random corruptions&lt;/a&gt; that you have no hopes of detecting.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Guard pages&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Not many Windows programmers are familiar with &lt;a href="http://msdn.microsoft.com/en-us/library/aa366549(VS.85).aspx"&gt;guard pages&lt;/a&gt;, but they are very important nonetheless. A guard page is a page protected by the &lt;em&gt;PAGE_GUARD &lt;/em&gt;page protection flag, which causes a one-shot page guard exception when the page is accessed. After the page is accessed, however, the guard is removed and will not be triggered again unless the page is protected by &lt;em&gt;PAGE_GUARD &lt;/em&gt;again.&lt;/p&gt;  &lt;p&gt;Guard pages are used by a variety of applications, but they have one very important role: Ensuring that thread stacks are lazily expanded. The way thread stacks work on Windows is that although by default 1MB of stack space is reserved for each thread, the individual pages in that range are committed page-by-page, when the thread attempts to expand the stack by calling a method or allocating stack-based memory. What happens is that the next page that is about to be used for the thread’s stack is a guard page, and there’s an exception handler that catches the page guard exception, properly commits the page and, most importantly, places a guard on the next stack page.&lt;/p&gt;  &lt;p&gt;I suppose you can already see the potential for trouble if you touch guard pages using IsBadXxxPtr. The API will swallow the page guard exception like any other, and the exception handler responsible for placing a guard on the next stack page will not run. This means you just created a potential stack overflow where there was previously no reason for one to occur.&lt;/p&gt;  &lt;p&gt;There are also other examples of why guard pages can be useful, and in most of these cases the IsBadXxxPtr family of APIs defeats the mechanism behind guard pages in varyingly fatal ways.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Not to mention that bad pointers will crash you anyway&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;There’s also the more philosophical argument here. If you get a bad pointer (and I’m not talking about a NULL pointer here, which can be easily detected&lt;strong&gt;&lt;font color="#ff0000"&gt;*&lt;/font&gt;&lt;/strong&gt; by other means), what do you think you can do about it? If you have the privilege of returning an error code, do you think the program that gave you an invalid pointer in the first place is going to check the error code?&lt;/p&gt;  &lt;p&gt;What you often do by checking for “bad” pointers is turning a fail-fast crash into a subtle bug to be discovered maybe hours later. The worst thing that can happen if you have a memory corruption is that your application continues running. If you check for bad pointers, it’s as if you’re trying to &lt;em&gt;guarantee&lt;/em&gt; that your application continues running with a memory corruption.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;*&lt;/font&gt;&lt;/strong&gt; By “easily detected” I mean that NULL pointers are not really that hard to identify. Windows guarantees that the first 64KB of memory are a &lt;em&gt;PAGE_NOACCESS&lt;/em&gt; region, so there’s absolutely no chance that someone is handing you a valid address that is strictly smaller than 65,536. Corollary: It’s a &lt;a href="http://beta.blogs.microsoft.co.il/blogs/asafshelly/archive/2009/12/27/verifying-c-buffers.aspx"&gt;moot point&lt;/a&gt; to try detecting NULL pointers by using IsBadXxxPtr. It’s true that a NULL pointer is not always NULL, e.g. if you’re accidentally obtaining a pointer to a field in a NULL structure pointer or obtaining a pointer to a member using a NULL &lt;em&gt;this&lt;/em&gt; pointer. However, in all these cases (unless you have structures bigger than 64KB, which is a whole different problem) you can simply test the address for &amp;lt; 64KB.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=498663" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/m4bqnV0mcUs" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Win32/default.aspx">Win32</category></item><item><title>Generating Prime Numbers in a Range (Was: LINQ Challenge), Part 4 – More on Sieves</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/15/generating-prime-numbers-in-a-range-was-linq-challenge-part-4-more-on-sieves.aspx</link><pubDate>Fri, 15 Jan 2010 16:17:57 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:498608</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=498608</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/15/generating-prime-numbers-in-a-range-was-linq-challenge-part-4-more-on-sieves.aspx#comments</comments><description>&lt;p&gt;As it is often the case with algorithms, there’s a better one yet for the problem at hand. The Sieve of Eratosthenes that we employed in the previous step is significantly faster than naively testing every prime number in the range, but there are additional improvements on this approach.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Atkin"&gt;Sieve of Atkin&lt;/a&gt; is a much smarter algorithm that relies on certain properties of modulo-sixty remainders of prime numbers. The algorithm is based on the following facts (and do feel free to check the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Atkin"&gt;Wikipedia entry&lt;/a&gt; for more details):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;All numbers with a modulo-sixty remainder that is divisible by 2, 3, or 5 are not prime because they are divisible by 2, 3, or 5, respectively. (This leaves only a handful of modulo-sixty remainders to consider.) &lt;/li&gt;    &lt;li&gt;All numbers with a modulo-sixty remainder 1, 13, 17, 29, 37, 41, 49, or 53 have a modulo-four remainder of 1 (because these remainders themselves have a modulo-four remainder of 1). These numbers are prime iff the number of solutions to &lt;em&gt;4x^2 + y^2 = n&lt;/em&gt; is odd and the number is not a square of another integer. (The proof to this and the following two claims is &lt;a href="http://www.ams.org/mcom/2004-73-246/S0025-5718-03-01501-1/S0025-5718-03-01501-1.pdf"&gt;here&lt;/a&gt;, behind a paywall.) &lt;/li&gt;    &lt;li&gt;All numbers with a modulo-sixty remainder 7, 19, 31, or 43 have a modulo-six remainder of 1. These numbers are prime iff the number of solutions to &lt;em&gt;3x^2 + y^2 = n&lt;/em&gt; is odd and the number is not a square of another integer. &lt;/li&gt;    &lt;li&gt;All numbers with a modulo-sixty remainder 11, 23, 47, or 59 have a modulo-twelve remainder of 11. These numbers are prime iff the number solutions to &lt;em&gt;3x^2 - y^2 = n&lt;/em&gt; is odd and the number is not a square of another integer. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hence, a relatively straightforward algorithm can be used to enumerate all solutions to the above quadratic equations in our range &lt;em&gt;{2…N}. &lt;/em&gt;Another iteration of refinements will remove all numbers divisible by 2, 3, or 5 – and we have ourselves a sieve, the Sieve of Atkin.&lt;/p&gt;  &lt;p&gt;Efficiently implementing the Sieve of Atkin is not trivial – the straightforward algorithm given on the Wikipedia page is in fact slower than the Sieve of Eratosthenes. &lt;a href="http://cr.yp.to/primegen.html"&gt;Daniel J. Bernstein’s primegen&lt;/a&gt; is one of the most efficient implementations known, but it’s written in C and comparing its performance with that of a C# Sieve of Eratosthenes is not fair.&lt;/p&gt;  &lt;p&gt;Therefore, I embarked on some refinements to the Wikipedia-provided algorithm and obtained the following results: [“Full” refers to the &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx"&gt;most naive algorithm&lt;/a&gt;, “Sqrt” and “SqrtN2” to &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/12/generating-prime-numbers-in-a-range-was-linq-challenge-part-2-simple-optimizations.aspx"&gt;its optimizations&lt;/a&gt;, “Sieve” to the &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/14/generating-prime-numbers-in-a-range-was-linq-challenge-part-3-sieve-me-one.aspx"&gt;Sieve of Eratosthenes&lt;/a&gt; and “Atkin” to the Sieve of Atkin]&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;strong&gt;&lt;em&gt;N&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Full&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Sqrt&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;SqrtN2&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Sieve&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Atkin&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9998&lt;/td&gt;          &lt;td&gt;52&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;12998&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;16898&lt;/td&gt;          &lt;td&gt;139&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;21968&lt;/td&gt;          &lt;td&gt;277&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;28559&lt;/td&gt;          &lt;td&gt;371&lt;/td&gt;          &lt;td&gt;8&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;37127&lt;/td&gt;          &lt;td&gt;603&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;48265&lt;/td&gt;          &lt;td&gt;954&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;          &lt;td&gt;9&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;62745&lt;/td&gt;          &lt;td&gt;1554&lt;/td&gt;          &lt;td&gt;24&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;81569&lt;/td&gt;          &lt;td&gt;3051&lt;/td&gt;          &lt;td&gt;38&lt;/td&gt;          &lt;td&gt;21&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;106040&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;55&lt;/td&gt;          &lt;td&gt;30&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;137852&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;43&lt;/td&gt;          &lt;td&gt;5&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;179208&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;117&lt;/td&gt;          &lt;td&gt;62&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;6&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;232971&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;173&lt;/td&gt;          &lt;td&gt;89&lt;/td&gt;          &lt;td&gt;9&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;302862&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;237&lt;/td&gt;          &lt;td&gt;132&lt;/td&gt;          &lt;td&gt;12&lt;/td&gt;          &lt;td&gt;10&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;393721&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;346&lt;/td&gt;          &lt;td&gt;182&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;511837&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;482&lt;/td&gt;          &lt;td&gt;250&lt;/td&gt;          &lt;td&gt;23&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;665388&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;680&lt;/td&gt;          &lt;td&gt;352&lt;/td&gt;          &lt;td&gt;31&lt;/td&gt;          &lt;td&gt;23&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;865005&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;963&lt;/td&gt;          &lt;td&gt;506&lt;/td&gt;          &lt;td&gt;41&lt;/td&gt;          &lt;td&gt;30&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1124507&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1452&lt;/td&gt;          &lt;td&gt;775&lt;/td&gt;          &lt;td&gt;74&lt;/td&gt;          &lt;td&gt;43&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1461859&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1943&lt;/td&gt;          &lt;td&gt;999&lt;/td&gt;          &lt;td&gt;76&lt;/td&gt;          &lt;td&gt;52&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1900417&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2743&lt;/td&gt;          &lt;td&gt;1493&lt;/td&gt;          &lt;td&gt;133&lt;/td&gt;          &lt;td&gt;116&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2470542&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2008&lt;/td&gt;          &lt;td&gt;134&lt;/td&gt;          &lt;td&gt;106&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3211705&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;187&lt;/td&gt;          &lt;td&gt;124&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;4175217&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;349&lt;/td&gt;          &lt;td&gt;167&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;5427782&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;651&lt;/td&gt;          &lt;td&gt;247&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;7056117&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1048&lt;/td&gt;          &lt;td&gt;329&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9172952&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1680&lt;/td&gt;          &lt;td&gt;515&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;11924838&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2224&lt;/td&gt;          &lt;td&gt;643&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;15502290&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;841&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;In other words, the Sieve of Atkin is a significant improvement over the previous result, especially for very large ranges. A visualization is in place to show just how much better we got with these improvements:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_1F55A339.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_3CE77E38.png" width="519" height="303" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This graph is rather hard to read because the naive algorithm explodes very quickly and looks like a vertical asymptote; there’s also an easily observable difference between the two sieves and the “sqrt”-optimizations.&lt;/p&gt;  &lt;p&gt;The same on a log-log scale:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_08D2DEE5.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_6D4DDCE1.png" width="516" height="301" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We can learn a few things from this graph. Recall that after plotting a function &lt;em&gt;f(x)&lt;/em&gt; in a log-log scale, if we get a straight line with slope &lt;em&gt;M&lt;/em&gt;, it means &lt;em&gt;log x = M log y&lt;/em&gt;, or equivalently&lt;em&gt; log x = log (y^M)&lt;/em&gt;, so we get &lt;em&gt;x = y^M&lt;/em&gt;. Therefore:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The slopes of the two “sqrt”-optimizations are roughly the same, and therefore there’s no &lt;a href="http://en.wikipedia.org/wiki/Big_O_notation"&gt;big-O&lt;/a&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/font&gt; difference between the two algorithms. &lt;/li&gt;    &lt;li&gt;The slope of the naive algorithm is greater than 1, so the naive algorithm is “worse” than &lt;em&gt;O(n)&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;The slope of the Sieve of Eratosthenes goes up at ~2,000,000 while the slope of the Sieve of Atkin remains constant. Both have a slope &amp;lt; 1 for small ranges, so both are sub-linear. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In the next (and final) post I will summarize some of our findings and point out a couple of other ideas for implementing primality tests in ranges.&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/font&gt; Recall that a function &lt;em&gt;f(n)&lt;/em&gt; is big-O of &lt;em&gt;g(n)&lt;/em&gt;, i.e. &lt;em&gt;f(n) = O(g(n))&lt;/em&gt; if there exists a constant &lt;em&gt;c &lt;/em&gt;such that &lt;em&gt;f(n) = c g(n)&lt;/em&gt; for all &lt;em&gt;n&lt;/em&gt;. (The Wikipedia definition requires this criterion to hold for all &lt;em&gt;n&lt;/em&gt; &lt;em&gt;&amp;gt;&lt;/em&gt; some constant, but it’s really irrelevant in the big picture.) Therefore, if the slope of two functions &lt;em&gt;f&lt;/em&gt;, &lt;em&gt;g&lt;/em&gt; is the same on a log-log scale, but their y-intercept is different, then we have: &lt;em&gt;y1 + log f(x) = y2 + log g(x)&lt;/em&gt;&lt;em&gt;. &lt;/em&gt;From this, &lt;em&gt;log f(x) = (y1 – y2) + log g(x)&lt;/em&gt; and therefore &lt;em&gt;f(x) = exp (y1 – y2) g(x)&lt;/em&gt;, but &lt;em&gt;exp (y1 – y2)&lt;/em&gt; is a constant and the definition of big-O holds.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=498608" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/hueMaU2Jabo" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Generating Prime Numbers in a Range (Was: LINQ Challenge), Part 3 – Sieve Me One</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/14/generating-prime-numbers-in-a-range-was-linq-challenge-part-3-sieve-me-one.aspx</link><pubDate>Thu, 14 Jan 2010 10:27:46 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:497162</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=497162</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/14/generating-prime-numbers-in-a-range-was-linq-challenge-part-3-sieve-me-one.aspx#comments</comments><description>&lt;p&gt;It’s time for the big guns. We’ve &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/12/generating-prime-numbers-in-a-range-was-linq-challenge-part-2-simple-optimizations.aspx"&gt;already seen simple optimizations&lt;/a&gt; to the problem of generating the prime numbers in a range.&lt;/p&gt;  &lt;p&gt;A completely different approach, the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt;, is based on a very simple idea. Write down all the numbers in the range &lt;em&gt;{1…N}&lt;/em&gt;. Mark 2 as prime. Now strike out every multiple of 2 as composite. Move on to the next number that is not marked as composite yet, and strike out every multiple of it as composite. (The next number, incidentally, is 3; then 5; then 7; and so on.)&lt;/p&gt;  &lt;p&gt;After &lt;em&gt;Sqrt[N]&lt;/em&gt; steps you have a list of all prime numbers; these are the numbers you did not strike out as composite. An implementation:&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;static int[] Sieve(IEnumerable&amp;lt;int&amp;gt; range)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int highBound = range.Last();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; bool[] sieve = new bool[highBound];       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int sqrt = (int)Math.Sqrt(highBound);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for (int i = 2; i &amp;lt;= sqrt; ++i)       &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; if (sieve[i - 1])//this was already marked as composite       &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; continue; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int j = 2 * i; j &amp;lt;= sieve.Length; j += i)      &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; sieve[j - 1] = true;//composite       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sieve[1 - 1] = true;//1 is not prime       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;int&amp;gt; numbers = new List&amp;lt;int&amp;gt;();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for (int i = 1; i &amp;lt;= sieve.Length; ++i)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (!sieve[i - 1])       &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; numbers.Add(i);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return numbers.ToArray();       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The biggest drawback of using a sieve is its memory utilization. We’re using &lt;em&gt;O(N)&lt;/em&gt; bytes of memory to store Boolean variables representing whether the number is prime or composite. [To save initialization costs, I assume that &lt;em&gt;sieve[i]&lt;/em&gt; is false if the number is prime; otherwise, we’d have to initialize the sieve to true, which is a costly operation. BTW, it’s possible to use a single bit per integer instead of a whole &lt;em&gt;bool&lt;/em&gt;. This is left as an exercise for the reader.]&lt;/p&gt;  &lt;p&gt;As for the runtime complexity, well, we’re doing at most &lt;em&gt;Sqrt[N]&lt;/em&gt; iterations through the sieve with values &lt;em&gt;{2…Sqrt[N]}&lt;/em&gt;. For each value &lt;em&gt;k&lt;/em&gt; in this range, we perform &lt;em&gt;(N/k)-1&lt;/em&gt; operations, marking the elements in the sieve as composite. One attempt to arrive to an upper bound is by saying that we have at most &lt;em&gt;Sqrt[N]&lt;/em&gt; iterations and each iteration performs at most &lt;em&gt;N/2&lt;/em&gt; operations, hence we have ourselves an &lt;em&gt;O(N^(3/2))&lt;/em&gt; algorithm. However, this upper bound is very far from being tight, and the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#cite_note-3"&gt;real upper bound&lt;/a&gt; is somewhere between &lt;em&gt;O(N) &lt;/em&gt;and &lt;em&gt;O(N(Log[Log[N]]))&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Fortunately, the sieve fares very well in comparison to the other alternatives, because the whole purpose of our little exercise is to generate prime numbers in a big range. If we were concerned with primality testing of a small set of numbers, a sieve wouldn’t fit our purposes&lt;font color="#ff0000"&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/font&gt;; here, however, it scales much better than the iterative alternatives.&lt;/p&gt;  &lt;p&gt;Here are some results: [run times in ms, “Full”, “Sqrt” and “SqrtN2” refer to the algorithms presented in the &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx"&gt;previous&lt;/a&gt; &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/12/generating-prime-numbers-in-a-range-was-linq-challenge-part-2-simple-optimizations.aspx"&gt;posts&lt;/a&gt;]&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="0" align="center"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;strong&gt;&lt;em&gt;N&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Full&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Sqrt&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;SqrtN2&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Sieve&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9998&lt;/td&gt;          &lt;td&gt;52&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;12998&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;16898&lt;/td&gt;          &lt;td&gt;139&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;21968&lt;/td&gt;          &lt;td&gt;277&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;28559&lt;/td&gt;          &lt;td&gt;371&lt;/td&gt;          &lt;td&gt;8&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;37127&lt;/td&gt;          &lt;td&gt;603&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;48265&lt;/td&gt;          &lt;td&gt;954&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;          &lt;td&gt;9&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;62745&lt;/td&gt;          &lt;td&gt;1554&lt;/td&gt;          &lt;td&gt;24&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;81569&lt;/td&gt;          &lt;td&gt;3051&lt;/td&gt;          &lt;td&gt;38&lt;/td&gt;          &lt;td&gt;21&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;106040&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;55&lt;/td&gt;          &lt;td&gt;30&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;137852&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;43&lt;/td&gt;          &lt;td&gt;5&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;179208&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;117&lt;/td&gt;          &lt;td&gt;62&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;232971&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;173&lt;/td&gt;          &lt;td&gt;89&lt;/td&gt;          &lt;td&gt;9&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;302862&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;237&lt;/td&gt;          &lt;td&gt;132&lt;/td&gt;          &lt;td&gt;12&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;393721&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;346&lt;/td&gt;          &lt;td&gt;182&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;511837&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;482&lt;/td&gt;          &lt;td&gt;250&lt;/td&gt;          &lt;td&gt;23&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;665388&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;680&lt;/td&gt;          &lt;td&gt;352&lt;/td&gt;          &lt;td&gt;31&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;865005&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;963&lt;/td&gt;          &lt;td&gt;506&lt;/td&gt;          &lt;td&gt;41&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1124507&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1452&lt;/td&gt;          &lt;td&gt;775&lt;/td&gt;          &lt;td&gt;74&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1461859&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1943&lt;/td&gt;          &lt;td&gt;999&lt;/td&gt;          &lt;td&gt;76&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1900417&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2743&lt;/td&gt;          &lt;td&gt;1493&lt;/td&gt;          &lt;td&gt;133&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2470542&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2008&lt;/td&gt;          &lt;td&gt;134&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3211705&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;187&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;4175217&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;349&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;5427782&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;651&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;7056117&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1048&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9172952&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1680&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;11924838&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2224&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Note that the sieve beats the iterative algorithms by a factor of 10 and sometimes more, making it a much more likely option for generating prime numbers in a large range (more than 11,000,000 numbers scanned in just a little more than 2 seconds). In our final installment, we’ll examine the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Atkin"&gt;Sieve of Atkin&lt;/a&gt;, a final refinement to the idea of generating primes using a sieve.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/font&gt; The whole idea of a sieve is feasible if you’re testing a very large range of numbers. If the method was called to calculate prime numbers in a range {K…K+100} where K is very large, creating a sieve up to K+100 would be prohibitive. Hence, for the measurements I used 1-based ranges.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=497162" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/_8AXKaijFxU" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Generating Prime Numbers in a Range (Was: LINQ Challenge), Part 2 – Simple Optimizations</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/12/generating-prime-numbers-in-a-range-was-linq-challenge-part-2-simple-optimizations.aspx</link><pubDate>Tue, 12 Jan 2010 12:27:04 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:494994</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=494994</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/12/generating-prime-numbers-in-a-range-was-linq-challenge-part-2-simple-optimizations.aspx#comments</comments><description>&lt;p&gt;There are two rather trivial optimizations to the &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx"&gt;problem of generating prime numbers that we saw in the previous post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;First there’s the observation that it suffices to test all potential divisors in the range &lt;em&gt;{2…Floor[Sqrt[K]]}&lt;/em&gt; to ascertain that &lt;em&gt;K&lt;/em&gt; is prime. This is not much harder to accomplish and is a significant running time optimization:&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;static int[] Sqrt(IEnumerable&amp;lt;int&amp;gt; range)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return range.Where(n =&amp;gt;       &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; if (n == 2) return true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int sqrt = (int)Math.Sqrt(n);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int i = 2; i &amp;lt;= sqrt; ++i)       &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; if (n % i == 0)       &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; return false;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }).ToArray();       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The idea is still the same – we iterate over lots of numbers and check if own target is divisible by these numbers. However, this “lots of numbers” is much less than the “lots of numbers” we had earlier.&lt;/p&gt;  &lt;p&gt;Specifically, we’re still not using any memory other than a constant amount, but the runtime complexity has improved significantly. This time, for each of the prime numbers in the range &lt;em&gt;K&lt;/em&gt; we do at most &lt;em&gt;Sqrt[K]&lt;/em&gt; iterations of the inner loop. Assuming as earlier that there are roughly &lt;em&gt;2Sqrt[N]/Log[N]&lt;/em&gt; numbers, the biggest possible number is &lt;em&gt;N&lt;/em&gt;, and the amount of work per number is &lt;em&gt;Sqrt[N]&lt;/em&gt;, we obtain an upper bound of &lt;em&gt;2N/Log[N]&lt;/em&gt; on the amount of work. (This disregards the work needed for the composite numbers; this is an assumption we’ve made before.)&lt;/p&gt;  &lt;p&gt;This is a big improvement – the difference between &lt;em&gt;N^2&lt;/em&gt; and &lt;em&gt;N^(3/2)/Log[N] &lt;/em&gt;is quite telling, and so is the difference between &lt;em&gt;N^(3/2)/Log[N]&lt;/em&gt; and &lt;em&gt;N/Log[N]&lt;/em&gt;. Here’s a graph:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_7ADA1DCD.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_38F3387F.png" width="515" height="313" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now we can introduce another optimization. It won’t reap us as many fruits as the previous algorithmic improvement, but it’s still worthwhile. Specifically, we note that there’s already a special treatment of the number 2 in our method. Why don’t we automatically discard all even numbers before embarking on the &lt;em&gt;Math.Sqrt&lt;/em&gt; call, which is quite expensive?&lt;/p&gt;  &lt;p&gt;Furthermore, if we discard all the even numbers in advance, we can start the loop from 3 and advance through only the odd numbers. (Obviously if &lt;em&gt;K&lt;/em&gt; is divisible by &lt;em&gt;2k&lt;/em&gt; then &lt;em&gt;K&lt;/em&gt; is divisible by 2, hence there’s no need to test even divisors other than 2.)&lt;/p&gt;  &lt;p&gt;This brings us to:&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;static int[] SqrtN2(IEnumerable&amp;lt;int&amp;gt; range)      &lt;br /&gt;{       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return range.Where(n =&amp;gt;       &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; if (n != 2 &amp;amp;&amp;amp; n % 2 == 0)       &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; return false;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int sqrt = (int)Math.Sqrt(n);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int i = 3; i &amp;lt;= sqrt; i += 2)       &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; if (n % i == 0)       &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; return false;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }).ToArray();       &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Not much complicated, but has a potential for running quite faster. For the even numbers, we’re not performing the expensive &lt;em&gt;Math.Sqrt&lt;/em&gt; call at all; for prime numbers, we’re going over half as many potential divisors as we did earlier. This is not an improvement if you’re analyzing theoretical runtime complexity, but from a practical standpoint it’s quite an improvement indeed: [times in ms, “Full” stands for the algorithm from the &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx"&gt;previous post&lt;/a&gt;]&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="0" align="center"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;strong&gt;&lt;em&gt;N&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Full&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Sqrt&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;SqrtN2&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9998&lt;/td&gt;          &lt;td&gt;52&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;12998&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;16898&lt;/td&gt;          &lt;td&gt;139&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;21968&lt;/td&gt;          &lt;td&gt;277&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;28559&lt;/td&gt;          &lt;td&gt;371&lt;/td&gt;          &lt;td&gt;8&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;37127&lt;/td&gt;          &lt;td&gt;603&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;          &lt;td&gt;7&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;48265&lt;/td&gt;          &lt;td&gt;954&lt;/td&gt;          &lt;td&gt;17&lt;/td&gt;          &lt;td&gt;9&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;62745&lt;/td&gt;          &lt;td&gt;1554&lt;/td&gt;          &lt;td&gt;24&lt;/td&gt;          &lt;td&gt;13&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;81569&lt;/td&gt;          &lt;td&gt;3051&lt;/td&gt;          &lt;td&gt;38&lt;/td&gt;          &lt;td&gt;21&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;106040&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;55&lt;/td&gt;          &lt;td&gt;30&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;137852&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;          &lt;td&gt;43&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;179208&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;117&lt;/td&gt;          &lt;td&gt;62&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;232971&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;173&lt;/td&gt;          &lt;td&gt;89&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;302862&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;237&lt;/td&gt;          &lt;td&gt;132&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;393721&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;346&lt;/td&gt;          &lt;td&gt;182&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;511837&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;482&lt;/td&gt;          &lt;td&gt;250&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;665388&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;680&lt;/td&gt;          &lt;td&gt;352&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;865005&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;963&lt;/td&gt;          &lt;td&gt;506&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1124507&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1452&lt;/td&gt;          &lt;td&gt;775&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1461859&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;1943&lt;/td&gt;          &lt;td&gt;999&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1900417&lt;/td&gt;          &lt;td&gt;&amp;#160;&lt;/td&gt;          &lt;td&gt;2743&lt;/td&gt;          &lt;td&gt;1493&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Predictably enough, for values of &lt;em&gt;N&lt;/em&gt; both small and large, the new version is almost twice as fast as the first one. Still, it takes us 1.5 seconds to generate less than 2,000,000 prime numbers. This scales linearly, but it’s still far from ideal.&lt;/p&gt;  &lt;p&gt;The massive breakthrough can be obtained by using the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt;, which is a completely different approach for generating prime numbers in a range. We’ll examine it in the next installment.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=494994" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/96T6AxjbTvA" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Generating Prime Numbers in a Range (Was: LINQ Challenge), Part 1 – Introduction</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx</link><pubDate>Mon, 11 Jan 2010 21:33:04 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:494244</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=494244</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/11/generating-prime-numbers-in-a-range-was-linq-challenge-part-1-introduction.aspx#comments</comments><description>&lt;p&gt;Justin Etheredge posted a nice &lt;a href="http://www.codethinked.com/post/2010/01/08/TekPubs-Mastering-LINQ-Challenge.aspx"&gt;LINQ challenge&lt;/a&gt; – write a LINQ query, using whatever chained lambdas you want, but no custom LINQ methods, to generate the prime numbers in a given range.&lt;/p&gt;  &lt;p&gt;Over at his blog, &lt;a href="http://www.codethinked.com/post/2010/01/10/The-TekPub-LINQ-Challenge-Part-2-Faster-Algorithms.aspx"&gt;Justin analyzes a couple of possible implementations&lt;/a&gt; with real LINQ queries (although the more efficient of them will have fairly complex lambdas in the query). I, on the other hand, would like to focus on the lessons you can learn from this kind of simple exercise, without using LINQ queries for now.&lt;/p&gt;  &lt;p&gt;Here are the rules of engagement for this mini-series of posts: We want to implement a method that takes an &lt;em&gt;IEnumerable&amp;lt;int&amp;gt;&lt;/em&gt; which is the range of numbers and returns an &lt;em&gt;int[]&lt;/em&gt; which is an array of all prime numbers within that range. [It would be unfair to some algorithms if we require that an enumerable is returned, as it would be unfair to return a sieve that specifies which numbers are prime and which aren’t.]&lt;/p&gt;  &lt;p&gt;Primality-wise, 1 is not a prime, but it doesn’t matter because no one will pass a range that starts with 1; 2 is a prime, so it 3, and so on.&lt;/p&gt;  &lt;p&gt;Without further ado, here’s the most naive thing conceivable:&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;static int[] Full(IEnumerable&amp;lt;int&amp;gt; range)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return range.Where(n =&amp;gt;      &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; if (n == 2) return true;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (int i = 2; i &amp;lt; n; ++i)      &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; if (n % i == 0)      &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; return false;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }).ToArray();      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This is rather horrible; we iterate over the entire sequence and for each element, check whether it’s prime by going through all possible candidates for a composite divisor and checking them individually. The &lt;em&gt;ToArray()&lt;/em&gt; call at the end materializes the query.&lt;/p&gt;  &lt;p&gt;Let’s attend to the complexity of this method. It does not use any additional memory (more accurately, it uses only a constant amount of memory that is not a function of the range size), which is a positive characteristic. However, its runtime complexity leaves much to be desired. Here’s a simple upper bound on its runtime, assuming that the range is &lt;em&gt;{1…N}&lt;/em&gt; for some &lt;em&gt;N&lt;/em&gt;:&lt;/p&gt;  &lt;p&gt;For each number &lt;em&gt;k&lt;/em&gt; in &lt;em&gt;{1…N}&lt;/em&gt;, the algorithm performs &lt;em&gt;k&lt;/em&gt; iterations of the loop if the number is prime, and less than &lt;em&gt;k&lt;/em&gt; iterations if the number is composite. Therefore, the total number of steps performed by the algorithm is at most &lt;em&gt;N(N+1)/2&lt;/em&gt;, or &lt;em&gt;O(N^2)&lt;/em&gt;. This is not a tight upper bound, because not all numbers in the range are prime (in fact, 50% of the numbers require only one step of the loop; another 33% of the numbers require only two steps; etc.).&lt;/p&gt;  &lt;p&gt;Another approach for estimating the runtime complexity is evaluating the number of primes in the range &lt;em&gt;{1…N}&lt;/em&gt;, because these are the numbers that are expensive to test. A &lt;a href="http://en.wikipedia.org/wiki/Prime-counting_function"&gt;known result for the number of primes less than &lt;em&gt;X&lt;/em&gt;&lt;/a&gt; is roughly &lt;em&gt;2Sqrt[x]/Log[X]&lt;/em&gt;. For each of these numbers &lt;em&gt;k&lt;/em&gt; we perform roughly &lt;em&gt;k&lt;/em&gt; iterations inside the loop; the biggest possible one is &lt;em&gt;N&lt;/em&gt; and therefore we perform at most &lt;em&gt;N(2Sqrt[N]/Log[N])&lt;/em&gt; operations, or &lt;em&gt;O(N^(3/2)/Log[N]))&lt;/em&gt;. This is much better than &lt;em&gt;O(N^2)&lt;/em&gt; and is a tighter bound on the runtime complexity of our algorithm. It really grows much slower – here’s a plot of the two functions:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_7644B54E.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_7B46F2FD.png" width="505" height="299" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This doesn’t change the fact that it’s really horribly slow. Here are some results for relatively small values of &lt;em&gt;N&lt;/em&gt;, times shown in milliseconds: [measured on my machine, of course]&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="0" align="center"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;strong&gt;&lt;em&gt;N&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;Runtime (ms)&lt;/strong&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;9998&lt;/td&gt;          &lt;td&gt;52&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;12998&lt;/td&gt;          &lt;td&gt;81&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;16898&lt;/td&gt;          &lt;td&gt;139&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;21968&lt;/td&gt;          &lt;td&gt;277&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;28559&lt;/td&gt;          &lt;td&gt;371&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;37127&lt;/td&gt;          &lt;td&gt;603&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;48265&lt;/td&gt;          &lt;td&gt;954&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;62745&lt;/td&gt;          &lt;td&gt;1554&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;81569&lt;/td&gt;          &lt;td&gt;3051&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There are some &lt;em&gt;significant&lt;/em&gt; improvements that can be made to this. The most trivial of all is known to any high school student: If you’re checking whether &lt;em&gt;K&lt;/em&gt; is prime, you don’t have to test all the factors &lt;em&gt;{2…K}&lt;/em&gt; – it’s enough to test all the factors &lt;em&gt;{2…Floor[Sqrt[K]]}&lt;/em&gt; and you’re good. We’ll attend to that in the next installment.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=494244" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/w5wF83Mj87k" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Beware of Evil Wizards</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/09/beware-of-evil-wizards.aspx</link><pubDate>Sat, 09 Jan 2010 16:18:37 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:491561</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=491561</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/09/beware-of-evil-wizards.aspx#comments</comments><description>&lt;p&gt;Ten years ago, Andrew Hunt and David Thomas published the incredible book, &lt;a href="http://pragprog.com/the-pragmatic-programmer"&gt;“The Pragmatic Programmer: From Journeyman to Master”&lt;/a&gt;. It’s not that I like this book because it has taught me so many things; I mainly like this book because of what it has &lt;em&gt;not&lt;/em&gt; taught me.&lt;/p&gt;  &lt;p&gt;And one thing this book has &lt;em&gt;not&lt;/em&gt; taught me is to use Add New Item –&amp;gt; “Some Amazing Technology” Class Template and then just adjust the grid on the control ever so slightly, and bam – there’s your user interface in all its glory.&lt;/p&gt;  &lt;p&gt;Here’s what “The Pragmatic Programmer” has to say about it:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[…] Tool makers and infrastructure vendors have come up with a magic bullet, the wizard. Wizards are great. […] But using a wizard designed by a guru does not automatically make Joe developer equally expert. […] Don’t Use Wizard Code You Don’t Fully Understand.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Why is that that we developers should not rely on wizard-generated code, but it’s OK for us to rely on the operating system’s code or on the .NET Framework’s code?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[…] We’d feel the same about wizards if they were simply a set of library calls […] that developers could rely on. But they’re not. Wizards generate code that becomes an integral part of Joe’s application. […] Eventually, it stops being the wizard’s code and starts being Joe’s.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s funny how these words never ceased to be true. Despite the ten-year-old warning against Evil Wizards, code generation inside the development environment has become an increasingly popular technique, and not just for spiffy user interface generation. Here are two wizards I use all the time, in Visual Studio:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Adding a WCF service reference generates a whole bunch of proxy code into your project, and not just the bare minimum service contracts and data contracts that you would otherwise write by hand; &lt;/li&gt;    &lt;li&gt;Dragging a table across a LINQ to SQL design surface generates a strongly-typed data context, an entity class for each table, relationships between entities, identity constraints and whatnot. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ten years after “The Pragmatic Programmer”, I’m not saying that you should stop using the Visual Studio wizards to generate code for you. But if you don’t understand the code generated by the wizard even though you’re using and adapting it to your needs, you’re in for some great trouble. (Unfortunately, presenters at conferences and class teachers are often guilty of spreading the trouble.&lt;strong&gt;&lt;font color="#ff0000"&gt;*&lt;/font&gt;&lt;/strong&gt;)&lt;/p&gt;  &lt;p&gt;The telling sign is this: &lt;strong&gt;If a technology were easy enough so that you didn’t have to thoroughly learn it before applying it, why would there be a wizard for generating code associated with that technology?&lt;/strong&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;*&lt;/font&gt; &lt;/strong&gt;The most unfortunate thing is that sometimes even we, the public speakers who show other people the power of those Evil Wizards, don’t fully understand the code being generated by them. I had the chance to witness, time and again, a presenter showing a bunch of code effected by a simple click of a button, and when something goes wrong the only resort seems to be to regenerate the whole code from scratch. Is this something you would recommend to your fellow developers?&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=491561" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/v3Jp1bpLNYQ" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/RandomThoughts/default.aspx">RandomThoughts</category></item><item><title>C++ in Visual Studio 2010: Windows Platform Developers User Group</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/07/c-in-visual-studio-2010-windows-platform-developers-user-group.aspx</link><pubDate>Thu, 07 Jan 2010 08:33:03 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:488808</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=488808</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/07/c-in-visual-studio-2010-windows-platform-developers-user-group.aspx#comments</comments><description>&lt;p&gt;Almost two years ago, I wrote about the TR1, a set of additions to the C++ standard that was implemented in a Feature Pack for Visual Studio 2008. Back then, I gave the post a rather provocative title: &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2008/03/14/c-developers-just-got-lambdas.aspx"&gt;C++ Developers Just Got Lambdas?&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Well, now we’ve got them. The &lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;new C++ standard&lt;/a&gt;, dubbed &lt;a href="http://www2.research.att.com/~bs/C++0xFAQ.html"&gt;C++0x&lt;/a&gt; (where the x is going to be a hexadecimal digit, hopefully A) has lambda functions as one of its features. Visual Studio 2010 implements some of the standard (draft), including lambda functions.&lt;/p&gt;  &lt;p&gt;Yesterday I had the pleasure of presenting C++0x to a group of Windows C++ developers, at the &lt;a href="http://blogs.microsoft.co.il/blogs/alon/archive/2009/11/04/the-first-meeting-of-the-windows-platform-developers-user-group.aspx"&gt;Windows Platform Developers User Group&lt;/a&gt; organized by &lt;a href="http://blogs.microsoft.co.il/blogs/alon"&gt;Alon Fliess&lt;/a&gt; and &lt;a href="http://blogs.microsoft.co.il/blogs/pavely"&gt;Pavel Yosifovich&lt;/a&gt;. I tried my best to touch all aspects of C++0x, including auto variables, the new “for each” statement, lambda functions, static assertions, the “decltype” operator and a brief mention of rvalue references. [I plan to describe at least some of these features in greater detail in the future.]&lt;/p&gt;  &lt;p&gt;Here’s a teaser from the session’s code:&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;template &amp;lt;typename Iterator, typename Combiner&amp;gt;     &lt;br /&gt;auto aggregate(      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Iterator begin,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Iterator end,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Combiner comb,      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; decltype(comb(*begin,*begin)) initial)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; -&amp;gt; decltype(comb(*begin,*begin))      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; decltype(comb(*begin,*begin)) result = initial;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for (; begin != end; ++begin)      &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; result = comb(result,*begin);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return result;      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="CONSOLAS"&gt;auto add_f = [](int a,int b) { return a+b; };     &lt;br /&gt;list&amp;lt;int&amp;gt; numbers = …;      &lt;br /&gt;auto something = aggregate(numbers.begin(),numbers.end(),add_f,0);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Confused? Regardless of whether you attended the session, feel free to &lt;a href="http://cid-c7124ef4202f9ed5.skydrive.live.com/browse.aspx/Public/CPP%20in%20Visual%20Studio%202010"&gt;download the slides and code&lt;/a&gt;. The code is very detailed and shows off some really neat things you can do in C++0x, especially with applications of lambda functions. The language becomes much richer, and naturally much more complicated, but I believe that in the course of the next few years we’re all going to ask ourselves how we managed to write any C++ at all without the features of the new standard.&lt;/p&gt;  &lt;p&gt;By the way, if you have ideas for future meetings of the Windows Platform UG, or if you would like to deliver a presentation at the UG, I’m sure &lt;a href="http://blogs.microsoft.co.il/blogs/alon"&gt;Alon&lt;/a&gt; and &lt;a href="http://blogs.microsoft.co.il/blogs/pavely"&gt;Pavel&lt;/a&gt; will be more than happy to hear about it. (You can also contact me if you want to, and I will forward your suggestion to them.)&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=488808" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/7AAkyfE8aiE" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>SDP 2009: .NET Debugging Tutorial</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-net-debugging-tutorial.aspx</link><pubDate>Sat, 02 Jan 2010 16:09:19 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:483195</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=483195</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-net-debugging-tutorial.aspx#comments</comments><description>&lt;p&gt;A few days I delivered a full-day session titled “Debugging .NET Applications” at the &lt;a href="http://www.sela.co.il/s/sdp/default.html"&gt;Sela Developer Practice&lt;/a&gt;. The session was packed and I was really happy to see lots of people interested in .NET debugging – this seems to be an area of incessant popularity.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_5B9389C1.png"&gt;&lt;img title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_3F3621D4.png" width="508" height="47" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I only had one day to deliver lots of material – I basically tried to cram the entire &lt;a href="http://sela.co.il/syl/syllabus.aspx?CourseCode=DNDebug&amp;amp;CategoryID=165"&gt;.NET Debugging&lt;/a&gt; course I teach at Sela into a single day. We started with debugging basics such as dump files and symbols – and considering the dozens of ways to capture a dump these days, even seasoned programmers are in need of a refreshment. Next, we talked about Visual Studio debugging, including &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163606.aspx"&gt;Managed Debugging Assistants&lt;/a&gt; which are a great but often overlooked feature. Most of the day, however, was dedicated to the WinDbg + SOS duo, which I used to diagnose a couple of memory leaks, a deadlock, a crash, and other scenarios. At the very end I also had a little time to mention other tools, such as Process Explorer, Process Monitor, Application Compatibility Toolkit, Hawkeye, &lt;a href="http://www.stevestechspot.com/"&gt;SOSEX&lt;/a&gt;, my own &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2009/10/24/wait-chain-traversal-debugging-extension-for-windbg.aspx"&gt;Wait Chain Traversal helper&lt;/a&gt; and others.&lt;/p&gt;  &lt;p&gt;I thoroughly enjoyed the session, as always. If you attended the session (and even if you didn’t), you can download the code samples &lt;a href="http://cid-c7124ef4202f9ed5.skydrive.live.com/self.aspx/Public/SDP/SDP%20Dec09%20NET%20Debugging%20Code.zip"&gt;here&lt;/a&gt;. (Unfortunately, the presentations won’t be available online.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_62495D72.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_457BAE91.png" width="524" height="196" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;[To view the conference recordings, some of which are already available, with three sessions freely accessible to everyone, including the &lt;a href="http://iwebcast1web.you-niversity.com/SLVideoPLayer/Player.aspx?ID=1614b8f4-bf18-421f-a5aa-e85eb9fc4be0"&gt;3-hour MVPs panel&lt;/a&gt; on life, the universe and everything, &lt;a href="http://www.sela.co.il/s/sdp/Highligths.html"&gt;start here&lt;/a&gt;.]&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=483195" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/li16Gu6HRIA" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Tools/default.aspx">Tools</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/SDP/default.aspx">SDP</category></item><item><title>SDP 2009: Parallel Programming with .NET 4.0 and Visual Studio 2010</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-parallel-programming-with-net-4-0-and-visual-studio-2010.aspx</link><pubDate>Sat, 02 Jan 2010 15:53:51 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:483176</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=483176</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-parallel-programming-with-net-4-0-and-visual-studio-2010.aspx#comments</comments><description>&lt;p&gt;A few days ago, at the &lt;a href="http://www.sela.co.il/s/sdp/default.html"&gt;Sela Developer Practice&lt;/a&gt;, &lt;a href="http://blogs.microsoft.co.il/blogs/stiller"&gt;Eran&lt;/a&gt; and I delivered a session titled “Parallel Programming with .NET 4.0 and Visual Studio 2010”. In this session we wanted to highlight the new features for parallel programming in .NET 4.0 – the Task Parallel Library and PLINQ – as well as the new Visual Studio 2010 features in the debugging and profiling areas.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_5B9389C1.png"&gt;&lt;img title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_3F3621D4.png" width="508" height="47" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We started with what we call &lt;em&gt;explicit parallelism – &lt;/em&gt;manually creating tasks and specifying what to do when they execute and when they complete. We used tasks to show some neat design patterns such as a pipeline of tasks and a tree of tasks. Then, we moved to &lt;em&gt;implicit parallelism&lt;/em&gt; – using the facilities of the runtime to concurrently schedule a for loop and a foreach loop. At the end of the session we showed the new debugger windows and the new concurrency profiling mode.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_13DE22F1.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_3F4243EB.png" width="523" height="177" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The demos and slides that we used can be downloaded from &lt;a href="http://cid-c7124ef4202f9ed5.skydrive.live.com/self.aspx/Public/SDP/SDP%20Dec09%20Parallel%20Programming.zip"&gt;here&lt;/a&gt;. If you’re looking for more comprehensive samples, don’t miss the recently updated &lt;a href="http://code.msdn.microsoft.com/ParExtSamples"&gt;Microsoft samples for Parallel Programming&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;There will be video recordings of the conference available to attendees at the &lt;a href="http://www.sela.co.il/s/sdp/default.html"&gt;conference website&lt;/a&gt;, so don’t forget to check back.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=483176" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/BVJJdPFR1Oo" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/ParallelFX/default.aspx">ParallelFX</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/VS2010/default.aspx">VS2010</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/SDP/default.aspx">SDP</category></item><item><title>SDP 2009: Building Workflow Services with WF 4.0 and WCF 4.0</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-building-workflow-services-with-wf-4-0-and-wcf-4-0.aspx</link><pubDate>Sat, 02 Jan 2010 15:44:14 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:483167</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=483167</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2010/01/02/sdp-2009-building-workflow-services-with-wf-4-0-and-wcf-4-0.aspx#comments</comments><description>&lt;p&gt;&lt;a&gt;Eran&lt;/a&gt; and I delivered a session titled “Building Workflow Services with WF 4.0 and WCF 4.0” at the &lt;a href="http://www.sela.co.il/s/sdp/default.html"&gt;Sela Developer Practice&lt;/a&gt; on Tuesday. This session was all about integrating the new features of WF 4.0 and WCF 4.0 to create a workflow application that orchestrates the execution of multiple WCF services.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_5B9389C1.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_3F3621D4.png" width="508" height="47" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;During the session, we showed how to use WCF 4.0’s ad-hoc discovery, how to write declarative workflows and use custom activities, how to take advantage of the built-in messaging activities in WF 4.0 and how to integrate a workflow application into Windows Server AppFabric. It shows off basic and advanced features of WF 4.0 including bookmarking support, variables and arguments, persistence participants, tracking participants and more.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/sasha/image_435FF999.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.microsoft.co.il/blogs/sasha/image_thumb_4EA90DD6.png" width="394" height="256" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The demos and slides that we used are available &lt;a href="http://cid-c7124ef4202f9ed5.skydrive.live.com/self.aspx/Public/SDP/SDP%20Dec09%20Workflow%20Services.zip"&gt;here&lt;/a&gt; – feel free to use our sample application to learn more about WF 4.0, WCF 4.0 and workflow services.&lt;/p&gt;  &lt;p&gt;Video recordings of the sessions will be available to attendees soon at the &lt;a href="http://www.sela.co.il/s/sdp/default.html"&gt;conference website&lt;/a&gt;. Stay tuned.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=483167" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/TlO0nf1jq_I" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/WF/default.aspx">WF</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/VS2010/default.aspx">VS2010</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/SDP/default.aspx">SDP</category></item><item><title>Fairness is Highly Overrated</title><link>http://blogs.microsoft.co.il/blogs/sasha/archive/2009/12/31/fairness-is-highly-overrated.aspx</link><pubDate>Thu, 31 Dec 2009 08:22:21 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:480394</guid><dc:creator>Sasha Goldshtein</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.microsoft.co.il/blogs/sasha/rsscomments.aspx?PostID=480394</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/sasha/archive/2009/12/31/fairness-is-highly-overrated.aspx#comments</comments><description>&lt;p&gt;Fairness with respect to synchronization mechanisms is a highly overrated property. When I talk about concurrency, parallelism, Windows synchronization and similar subjects, I’m often asked whether the specific algorithm, mechanism or feature is &lt;em&gt;fair&lt;/em&gt; in some respect.&lt;/p&gt;  &lt;p&gt;First, let’s define fairness. I’ll use a simplistic yet rigorous definition to define a &lt;em&gt;fair lock&lt;/em&gt;. (Other synchronization mechanisms may have fairness defined in a similar fashion.) To begin with, a lock is exactly what you think it is – a mechanism for specifying mutual exclusion. Given N threads that attempt to acquire the lock concurrently, only one thread may enter the lock at a given time. When that thread releases the lock, one other thread may enter the lock; and so on. We can assume for the sake of the definition that the work protected by the lock is bounded; i.e. no thread acquires the lock with the intention of retaining it indefinitely.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A lock is fair if, given N threads that attempt to acquire the lock, there is an upper bound on the amount of time any one of the N threads will wait before entering the lock.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;An alternative definition considers the number of times a thread is skipped before it is allowed to enter the lock, and discards the need to put a bound on the duration of work protected by the lock:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A lock is fair, if given N threads that attempt to acquire the lock, there is an upper bound on the number of times any one of the N threads will be skipped before entering the lock.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This sounds like a fairly trivial property, and one of the most trivial ways to implement this kind of fairness is using a queue (FIFO) to maintain the information about waiting threads. If waiting threads are enqueued into a FIFO, and the work protected by the lock is bounded, then the amount of time any individual thread will wait is also bounded, and the bound is linear in the number of threads that arrived before that thread.&lt;/p&gt;  &lt;p&gt;However, FIFO fairness is not always easy to attain. To begin with, some synchronization mechanisms don’t use queues of waiting threads because they are too expensive. For example, a &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2008/08/10/practical-concurrency-patterns-spinlock.aspx"&gt;spinlock&lt;/a&gt;, which is a purely user-mode synchronization mechanism requiring no system calls, does not use FIFOs of waiting threads at all, and hence is not fair. Extensions of spinlocks, such as queued spinlocks (MCS spinlocks) may provide fairness that is not necessarily linear. &lt;a href="http://en.wikipedia.org/wiki/Peterson&amp;#39;s_algorithm"&gt;Peterson’s algorithm for mutual exclusion&lt;/a&gt; provides a quadratic upper bound on fairness, implying that a thread may be skipped &lt;em&gt;O(N^2)&lt;/em&gt; times when N threads are completing for the lock.&lt;/p&gt;  &lt;p&gt;Even when FIFOs are used, a thread may be forced to leave the queue and be inserted at the back of the queue later on (on Windows, this can happen when an &lt;a href="http://msdn.microsoft.com/en-us/library/ms681951(VS.85).aspx"&gt;APC&lt;/a&gt; is executed on that thread). If this can happen an unbounded number of times, fairness cannot be guaranteed at all – and indeed, no synchronization mechanism on Windows is free from the risk of being interrupted by an APC. If the thread enters an &lt;a href="http://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx"&gt;alertable wait state&lt;/a&gt;, it can be preempted by a user mode APC; but even if it doesn’t cooperate, kernel mode APCs can still interrupt the thread and effect a reordering of the waiting queues.&lt;/p&gt;  &lt;p&gt;The most amazing thing of all about fairness is that it is not always a desired property even if it can be guaranteed with relative ease. Lock convoys are an excellent demonstration of how fairness can be devastating for a group of threads competing for the same synchronization mechanism. In a &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2008/07/30/practical-concurrency-patterns-lock-free-operations.aspx"&gt;lock convoy&lt;/a&gt; (which I discussed in detail &lt;a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2008/07/30/practical-concurrency-patterns-lock-free-operations.aspx"&gt;earlier&lt;/a&gt;), a group of threads acquires and releases a lock many times in a single quantum; however, when one of the threads is preempted while holding the lock, havoc ensues because any subsequent thread acquires the lock only once and is preempted as soon as it tries to acquire the lock again. This is a direct consequence of fairness, and demonstrates that fairness is not always desirable.&lt;/p&gt;  &lt;p&gt;When designing a synchronization mechanism or working with existing synchronization mechanisms, bear in mind that &lt;strong&gt;often&lt;/strong&gt; &lt;strong&gt;the progress of a group of threads (measured as throughput, CPU utilization or other metrics) can be shown to be higher if unfair synchronization mechanisms are used&lt;/strong&gt;. A single thread can “take one for the team” to maintain consistent global progress.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=480394" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/sashag/~4/SFQNEp7AJos" height="1" width="1"/&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/ParallelFX/default.aspx">ParallelFX</category><category domain="http://blogs.microsoft.co.il/blogs/sasha/archive/tags/Win32/default.aspx">Win32</category></item></channel></rss>
