No book is perfect and sometimes mistakes slip through. Here are the corrections, with page numbers that match the PDF and Print editions.

2nd Edition

  • Bookmarks/Links. PDF version only. Bookmarks and the Table of Contents links did not work in the PDF. [Fixed in version 2.1]
  • Chapter 1, Performance Measurement and Tools, “Average vs. Percentiles”, ePub and Kindle versions only. The formula to find the index of the Pth percentile should be 0.01 * P * N. The formula is correct in the printed and PDF editions. [Fixed in version 2.2]
  • Bibliography, page 465. A URL mistakenly had an extra “http://”. [Fixed in version 2.3]
  • Chapter 2, Memory Management, Pool Long-Lived Objects, Code sample, page 103. GetObject method has a null reference exception potential. [Fixed in version 2.4]
  • Chapter 4, Asynchronous Programming, TPL Dataflow Example, Code sample, page 228. Code sample had duplicate of Console.WriteLine(“Begin: getFileContents”) when it should have read “End: getFileContents” instead. However, this line was never printed anyway and only included for parity with other transformation blocks. [Line removed in version 2.4]
  • Chapter 4, Asynchronous Programming, async and await, page 246.  Paragraph after code sample mistakenly refers to an HTTP result, when it should instead refer to the write finishing. [Fixed in version 2.4]

1st Edition

These errors have been fixed in the eBook editions. If you have purchased the eBook from this site, please contact me and I can send you an updated copy.

  • Page 155, Chapter 5, “Class vs. Struct” – Object size is actually 8 bytes for 32-bit processes. Because of memory alignment, the minimum effective size is 12 bytes, but if have a single 4-byte field, the size of the object will still be only 12 bytes. The same principle is true for 64-bit processes, but the size is actually 16 bytes with a minimum effective size of 24 bytes. [Fixed in version 1.2]
  • Page 192, Chapter 6, “String Comparisons” – Two of the code samples are reversed. String.Compare(a, b, StringComparison.Ordinal) is faster than String.Compare(a, b, StringComparison.OrdinalIgnoreCase) [Fixed in version 1.3]
  • Page 216, Chapter 8, “Defining Events” – After the code sample, in the second paragraph, the sentence “Note that Keywords are treated like bit flags so you must assign values of multiples of two.”  should read “Note that Keywords are treated like bit flags so you must assign values of powers of two.” [Fixed in version 1.4]
  • Page 121, Chapter 4, “Use Tasks for Non-Blocking I/O” – The code example should use the following constructor for FileStream: var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, chunkSize, useAsync: true); This instructs the operating system to actually do asynchronous I/O. The original constructor would use synchronous I/O, but still use Tasks to make it seem asynchronous from your application’s point of view. The downloadable code samples have also been updated. [Fixed in version 1.4]
  • Page 22, Chapter 1, “Performance Counters” – The sentence “To setup a Data Collector Set, in the main PerfView window:” should read “To setup a Data Collector Set, in the main PerfMon window;”. [Fixed in version 1.5]
  • Page 138, Chapter 4 – Interlocked.CompareAndExchange should read Interlocked.CompareExchange.
  • Page 201, Chapter 6 – SequentialAccess should be SequentialScan.