APPENDIX Benchmark Test Harness for .NET

WHEN MIGRATING TO A new platform like .NET, many questions regarding perfor• manee arise. Presented with a ehoiee between multiple ways of aeeomplishing the same task, performanee ean often be the deciding faetor when figuring out whieh teehnique to use. Determining whieh teehnique is the quiekest may seem simple, but ean rapidly deteriorate into eomplexity. This appendix presents a performanee test harness that allows for eonsistent and robust exeeution of per• formanee test eases; the results of benehmark test harness were used to eonduet the tests that are presented in this book. Chapter 2 presents a diseussion of teeh• niques and praetiees that assist in developing an aeeurate benehmark, whereas the foeus of this appendix is a deseription of the implementation of the harness.

Comparing Performance

Analyzing the eomparative performanee of two or more software teehnologies involves two eritieal steps. The first step is deseribing a representative test ease for eaeh teehnology, and the seeond step is aeeurately timing the test eases. Deseribing a representative test ease is the domain of software engineering judg• ment and experienee, but there are a number of guidelines that ean help:

• Eaeh test ease should aeeomplish the same or similar end result. If the performanee of the stream-based XML parsing in the Framewerk Library is being eompared to the traditional DOM-based XML parsing, the XML test doeument and result proeessing for eaeh test should be as similar as possible.

• The supporting infrastrueture for the test ease should be the same as it is in produetion eases. For example, eonsider a pieee of eode that needs to pull data from SQL Server and eaehe the data in eustom business objeets. The System.Data.DataReader type should be the quiekest option, but System. Data. DataSet has some added funetionality that may be useful if the performanee delta is small. When testing the relative performanee, it is important that the eonfiguration of SQL Server and the load that the

249 Appendix

server is experiencing is the same as the production case. lt may turn out that running the stored procedure to collect that data and transporting it over the network takes 95 percent of the time, and the choice between DataReader and DataSet is insignificant in performance terms.

• The test case should be profiled to ensure that supporting code is not taking up a significant amount of the time. If a test is aimed at determining the performance cost of a virtual function compared to a nonvirtual function, ensure that the code inside the functions is not overly expensive.

• The test case should be conducted enough times to make the cost of setting up the test harness and calling the test method insignificant. A profiler can assist in making this determination.

• The test case should not be so insignificant that the ßT compiler can discard it. Inspection of the x86 assembly code generated by the ßT compiler for a release build of an assembly will allow a determination of the inlining and discarding that has occurred.

Once representative test cases have been chosen, conducting the tests seems like a simple step. The code that follows shows the simplest implementa• tion possible:

DateTime startTechniqueA = DateTime.Now; TestNamespace.TechniqueATest(); //run test DateTime endTechniqueA = DateTime.Now;

DateTime startTechniqueB = DateTime.Now; TestNamespace.TechniqueBTest(); //run test DateTime endTechniqueB = DateTime.Now;

TimeSpan timeTakenA = endTechniqueA - startTechniqueA; TimeSpan timeTakenB = endTechniqueB - startTechniqueB;

11 Console.Writeline( Test A: II + timeTakenA. ToString());

11 Console.Writeline( Test B: II + timeTakenB. ToString());

There are a few problems with this code:

• If the test case executes a method that has not been called previously, ßT compilation of the method will occur. This will distort the results in favor of the method without the ßT compiler hit.

250 Benchmark Test Harness for .NEI'

• The ordering of the tests may distort the results in some cases. For example, if data is being retrieved from SQL Server, the second test can run quicker due to caching by SQL Server.

• Same code is required to process the results of the tests into a form easily comprehensible. The code for result processing is not test specific, and should be factared out.

• Same tests will require setup and teardown functions to execute either side of the test, and the time taken for these functions should not be included in the test results. Mixing setup code with the timing functionality code obscures the intent of a function, and increases the chance of error.

• The results of some tests should be thrown out. Criteria for throwing a test result out are test specific, but will typically involve the occurrence of a significant event that takes processor time away from the executing test.

• Same tests should be executed on a priority thread to minimize the interference from other threads executing on the same processor. The code to set up a secondary test thread should be factared out into a reusable test harness.

• Same tests take a lang time to execute, and visual feedback of the test progress is desirable.

• The DateTime dass is not an accurate timer of operations that complete in under a second, and a timer with higher accuracy is preferable.

• It is possible for one test to run for a different number ofloops than other tests ifthe loop-termination literal is embedded in the test method. In the process oftesting, it is common to change the loop-termination literal a number of times until the tests run for a reasonable time period. Failing to have a formal method for using the same loop-termination literal in all tests can lead to incorrect results.

• A future version of the CLR may include a progressively optimizing JIT compiler, which implies the tests should be run a number of times to simulate the execution of critical path code in a real program.

This list highlights the need for a test harness that can alleviate these issues, which is presented in the following sections.

251 Appendix Implementing the Benchmark Test Harness

A number of issues need to be considered in the design of a hamess for generat• ing timing data on benchmark runs. Setting up and running test cases should not be overly onerous or difficult, and different categories of test runs need to be supported. Producing accurate results is the most important design goal, how• ever, and failure to achieve this goalwill render the test hamess useless. Choosing the correct technologies to use is as important as bug-free hamess code, and this section covers the motivation for the current implementation of thehamess.

Function Invocation

The first step in the hamess design is deciding how the test case will be created and executed, where a test case is defined as a method that contains the code necessary to exercise a technology or technique in a representative manner. Creating test cases should be simple, and the overhead of calling these functions should be minimal so as not to distort the test results. The (Cl..R) exposes a number of techniques for implementlog the function invocation section of the hamess. These include

• Interfaces: Each test could be contained in a class that implements a test interface. The interface would expose a RunTest method, and the hamess could iterate over a number of objects, calling the RunTest method on each.

• Reflection: Aseries of object references could be passed to the hamess, and a standard method, say Test, could be bound to and invoked on each object.

• Delegates: A test method delegate could be defined, and methods that contain test cases could be added to the delegate invocation list.

When using reflection, it is not possible to ensure that an object registering for performance testing exposes a Test method at compile time. Following the widely accepted programming principle that it is better to use compile-time enforcement over runtime error detection and the performance impact of late• bound method invocation, the use of reflection was rejected. The use of interfaces would require a separate type for each test method, which could become cumbersome. In contrast, delegates support the chaining tagether of a number of methods in a single invocation list, and allow for the use of numerous methods for the same type, as shown in the following snippet.

252 Benchmark Test Harness for .NEI'

Given these qualities, delegates where chosen as the function invocation mechanism. public delegate void DoSomething();

I/returns two delegate methods using the same return value public DoSemething ReturnDelegatelist(){ DoSemething ds = null; ds += new DoSomething(FirstDelegateMethod); ds += new DoSomething(SecondDelegateMethod); return ds; }

//another method in the same type that returns a single delegate public DoSemething ReturnSingleDelegate(){ return new DoSomething(FirstDelegateMethod); } public void FirstDelegateMethod(){ return; } public void SecondDelegateMethod(){ return; }

The cost of making the delegate call will be included in the overall timing for a test method call, and must be very small. The cost of maldng a function call is generallyproportional to the amount of indirection that the runtime must go through to locate the pointer to the underlying function. The level of indirection for "direct" calling technologies like static, instance, and virtual functions can be determined by the number of x86 MOV instructions needed to execute the call. An inspection of the x86 instructions that the ßT compiler produces to call a delegate indicates that only three MOV instructions are needed to locate the function pointer for the delegate method, which is less than the four MOV instructions required to call a virtual method through an interface. Having only three MOV instructions indicates very little indirection is required to call a delegate method.

Function Ordering

The order in which the test cases are called and the practices of only executing test functions for a single run were identified as problern areas earlier. The

253 Appendix

hamess needs to accommodate calling the test methods more than once and in a random order. The System. Delegate. Get!nvocationlist returns a Delegate array, making calling the test functions multiple times and in a random order simple. Generating a random sequence for test method call ordering is easy with the aid of the System. Random type, and is illustrated in the GetRandomSequence method in the test hamess:

//reference to a delegate list that is populated by the users of the harness Testease testeaseDel;

//get a list of individual delegates in random order Delegate[] testeases = testeaseDel.Getinvocationlist(); Int32 numberTesteases = testeases.Getlength(o); Int32 totalNumberRuns = numberTesteases*_numberRuns; Int32[] runNumberOrder = GetRandomSequence(numberTesteases, totalNumberRuns);

//run tests for (Int32 i = o; i < totalNumberRuns; ++i){ Int32 testeaseToRun = runNumberOrder[i]; Testease tc = (Testease)testeases[testeaseToRun]; I/start timer tc(_number!terations); //actual test case invocation //stop timer and record results }

//helper method to get test number execution in random sequence. protected virtual Int32[] GetRandomSequence(Int32 numberTesteases, Int32 totalNumberRuns){

//al stores a list of each test number in sequnce. A random number that //is bounded by the length of al is generated, and this test number is //removed from al and added to the return sequence.

Arraylist al = new Arraylist(totalNumberRuns); Int32[] retSequence = new Int32[totalNumberRuns]; for (int i = o; i < totalNumberRuns; ++i){ al.Add(i); } Random rand = new Random(); for (int j = totalNumberRuns - 1; j != -1; --j){ Int32 index = rand.Next(o, j+l); retSequence[totalNumberRuns-j-1] = (int)al[index] I _numberRuns; al.RemoveAt(index);

254 Benchmark Test Hamess for .NET

} return retSequence; }

Setup, Cleanup, and Test Result Rejection

Some test functions will need setup and cleanup code to be executed as part of the test, but the time taken to execute these functions should not be included in the test results. To achieve this, a delegate function is needed to allow cleanup functions to be defined for the test harness. An instance of the delegate may force a garbage collection or delete a series of files from a folder. The harness will check for the presence of pre- and post-cleanup methods, and call these ifpresent. The same technique can be used to register a delegate method that the harness can employ to determine if a partiewar test run is valid. A method that conforms to this delegate can be grouped with a collection of benchmark test cases and passed into the harness. After each test, the harness will call the test validity checking delegate method if present, and based on the results of this method, the test run may be rejected and rerun. A test harness property deter• mines the maximum number of retries the test harness will attempt before simply accepting a result. Erle Gunnerson's boxing tests presented on MSDN (http: I I msdn.microsoft.comllibraryldefault.asp?url=llibrarylenusldncscollhtmll csharp03152001. asp) provides a good example of a test suite where setup func• tionality is required. In Eric's test, the contents of a large text file are read using a stream, and a hash table is used to perform a count on the unique words contained in the file. The results presented showed that extracting the file from disk took about 70 percent of the test time, and the time taken for test initializa• tion code execution had to be manually discarded to understand the test results. The example application included in the book download samples (available at http: I lwww. apress. com) shows the tests rewritten using the test harness with the file 1/0 and stream initialization codeseparate from the real boxing tests.

Delegate Design

The test harness must expose delegates that define the retum value and para• meters that the test, cleanup, and validity functions must take. For cleanup functions, no generic retum types or parameters are required, and the following delegate declaration is used: public delegate void TestCleanup();

255 Appendix

It may initially appear that defining a delegate like this imposes a Iot of state-related restrictions on implementing functions, and that a delegate that takes an object[] parameter Iist would be better. This is not the case, and by using instance rather than static methods as delegates, state information can be used within the delegate function in a clean and object-oriented manner, as shown in the following snippet:

public class DelegateUse { public delegate void DoSomething();

public DelegateUse(int state){ _someStateParam = state; }

public void DelegateUsingState(){ DoSemething ds = new DoSomething(DelegateMethod); ds(); }

public void DelegateMethod(){ Console.Writeline(_someStateParam); } }

The delegate that defines a test case is slightly different. Most test cases involve iterating over a partiewar technique for a certain number of times. The number of iterations should be constant across all tests to ensure an accurate comparison is being made, and to make certain that this is the case, the iteration count is made a parameter of the test case delegate. The delegate used to define a test case is

public delegate void TestCase(Int32 number!terations);

Defining a group of test cases for execution by the harness is now a simple matter of authoring test methods that have the same function prototype as the delegate, and passing them to the harness for execution:

public class ExampleTest { [Benchmark("Compares Technique 1 with Technique 2")] public TestResultGrp RunTest() { const int numberiterations = 50000000; const int numberTestRuns = 5; TestRunner tr = new TestRunner(numberiterations, numberTestRuns); TestRunner.TestCase testCases =null;

256 Benchmark Thst Harness for .NET

testCases += new TestRunner.TestCase(Techniquel); testCases += new TestRunner.TestCase(Technique2);.

return tr.RunTests(testCases); }

public void Techniquel(Int32 numberlterations){ for (int i = o;i < numberlterations;++i) { //actual code for Techniquel here } }

public void Technique2(Int32 numberlterations){ for (int i = o;i < numberlterations;++i) { II Technique2 } } }

For tests that require pre- and post-cleanup functionality or the ability to discard the results of some tests, a TestGroup type is defined to group together the delegates for the test case. If all the TestGroup delegates arenot required, the test harness provides a NoOp method of the required signature. If a garbage collection should occur before a test case executes, but no action is required after the test case execution, the NoOp method can be used as the TestGroup post-cleanup method. The following snippet shows the ExampleTest type rewritten to force a garbage collection before each test case run: public class ExampleTest { public static void ForceGC(){ GC.Collect(); }

[Benchmark("Compares Technique 1 with Technique 2")] public TestResultGrp RunTest() { const int numberlterations = 50000000; const int numberTestRuns = 5; TestRunner tr = new TestRunner(numberlterations, numberTestRuns);

TestGroup tgTechniquel = new TestGroup( I/test case new TestRunner.TestCase(Techniquel), I/force a GC before test new TestRunner.TestCleanup(ForceGC),

257 Appendix

I/no action after test new TestRunner.TestCleanup(TestRunner.NoOp), lidefault validity test new TestRunner.TestValidity(TestRunner.TestOK)); tr.AddTestGroup(tgTechnique1);

TestGroup tgTechnique2 = new TestGroup( new TestRunner.TestCase(Technique2), new TestRunner.TestCleanup(ForceGC), new TestRunner.TestCleanup(TestRunner.NoOp), new TestRunner.TestValidity(TestRunner.TestOK)); tr.AddTestGroup(tgTechnique2);

return tr.RunTests(null); }

public void Technique1(Int32 number!terations){ for (int i = o;i < number!terations;++i) { //actual code for Technique1 here } }

public void Technique2(Int32 numberiterations){ for (int i = o;i < number!terations;++i) { II Technique2 } } }

Test Execution

The test harness has now been defined to the point where it is known that a delegate of test cases will be available, and some of these test cases will have supporting delegates. The test case delegates need to be executed, and the time tak.en for each run must be monitared and recorded. The Iist of qualities that a robust and reliable test harness should possess imposes three restrictions on the test case execution: the ability to run on a high-priority thread must be sup• ported; the test cases should be executed a number of times to negate the effects of JIT compilation, module loading, and other once-off performance hits; and the user should be given feedback ab out the progress of the test execution. These criteria necessitate that the test cases should be executed on a secondary thread, and all tests should be executed a number of times.

258 Benchmark Test Hamess for .NEI

The .NET Framework makes multithreading a simple exercise. The System. Threading. ThreadStart delegate allows for the nomination ofthe function to execute when a thread starts, and the.thread priority is a public property of the System. Threading. Thread type. The test hamess uses adefault thread priority ofThreadPriority .Highest, and an overloaded method allows the thread priority to be specified for a test run. The tests are timed using the high-resolution QueryPerformanceCounter func• tion exported by kemel32.dll. A wrapper typethat allows the high-resolution timing capability of QueryPerformanceCounter to be used without repetition of the arithmetic necessary to derive real-world time data has been developed by Shawn Van Ness (http: I /www. arithex. com/hirestimer. es. html), and this type is used in the benchmark hamess. A running test case supports interaction with the user by displaying a dia• log-based progressbarthat provides an indication of the test case's progress. An event is raised after the execution of each test case, and the completion percentage of the tests is available through an event delegate parameter. The user can cancel a running test case via a Cancel button on the Progress dialog box. System. Threading provides a mechanism to terminate threads in a clean and safe manner by exposing a Thread. Abort method, which throws a ThreadAbortException inside the thread, allowing any nonmemory resources to be freed prior to the thread exiting. Executing the test cases can now produce a reetangular array of System. TimeSpan values that represents all the test results.

Result Analysis and Presentation

A stand-alone array of System. TimeSpan values that represent test results, viewed through a message box or debugger window, is not the most easily digestible form of information. Some basic statistical analysis would be beneficial. To support this analysis, a TestResult type is defined to store the results. The type contains fields for TestName (extracted from the test delegate via reflection); a string array indicating any errors that occurred during test execution; the raw results; minimum, maximum, mean, and median statistics; and the median normalized to the lowest medium of all test results. Median, which is defined as the middle value in a sorted range, is used in preference to the mean to prevent the results being distorted by outliers that may be due to extemal events inter• fering with a partiewartest run. The TestResul t type and test result processing function support extensibility through inheritance. Three methods of result presentation were implemented for the test hamess: XML file output, chart output, and message box display. XML output is implemented using the XmlTextWriter type, which makes the creation ofwell• formed XML files extremely easy, and is much easier to use than the DOM -based approach affered by XmlDocument.

259 Appendix

Chart output was accomplished using the MSCHART ActiveX control that shipped with Visual Studio 6. No .NET charting component has been released when the test harness was written, and the ActiveX control interoperability tech• nology in the .NET Framework is quite stable and reliable. The chart output allows two types of interchangeable chart presentation: a 3D bar chart and a 2D bar chart. The 3D bar chart displays the derived test result data for all tests, and allows for quick identification of test result outliers. The 2D bar chart shows only the normalized medium of the test cases, and is what is typically used for the ultimate analysis of the different test cases (see Figure A-1).

~ ChartOutputform - - ~[QJL8J ISurmoy ::1

NonNI-Md Modan

14 14

12 12

10 10

08 08

06 06

04 04

02 02

00 00

Figure A -1. Two-dimensional bar chart showing test results

Message box output is supported as a quick and easy form to view all the test result data, and the ability to capture the text of a message box using Control-C in Windows 2000 and above makes the messagebox output a good option when the results of the tests need to be easily included in a text docu• ment. Figure A-2 shows the textbox output for the same results shown graphically in Figure A-1.

260 Benchmark Test Hamess for .NET

BoldngTnt -"""'-"" ~bomghtsln<*

FigureA-2. Message box output ofthe test results

Test Harness Architectural Summary

The final system architecture is shown in Figure A-3. A clean separation of test execution, progress display, and result presentation has been achieved, and extensibility of the test hamess is possible in a number of ways. The following Iist details extensibility points, and makes reference to types and methods shown in Figure A-3:

• Output. DisplayResul ts has an overloaded version that allows a new object derived from Resul tOutput .Output to be passed in. A hypothetical DatabaseOutput type could be passed into this method, allowing test results to be persisted to a database.

• The TestResult type can be derived from to add additional statistical parameters.

• TestRunner can be derived from to provide an extended implementation of PostProcessResul ts if advanced statistical analysis is required.

• A new listener can be registered for PercentageDoneEventHandler to allow an alternative test progress display mechanism to be used. The default Wmdows Forms-based progress dialag box can be tumed off using an overloaded version of TestRunner. RunTests.

• Authoring and running new test cases is simple.

261 Appendix

•delegate• •delegate• odelegate• TestValidity Testease TestCleanup •event• PercentaplloneEventllandler

T I Systa. Windaoos.~.Fon cccontains» «contains» I I I I cccontains» «contains» I I J' I TestRunner I I lA ------: f+RunTests(in TesteaseDei : TestCase) : TestResult ""ostProcessResults(in TestRunlimes : TimeSpan) : TestResult I ..OnPercentageChange() I------~ I I TestResult'"' +TestName : String +ErrorDescription : String tTestResults : TimeSpan +Min : TimeSpan +Max : TimeSpan ------,I +Mean : TimeSpan I +Median : TimeSpan I +NormalisedTimeSpan : float I I I I I

OUtput 1 •enumeration» ~isplayOption 1 f+MessageBox i ~t~~t~:~u~~!gin Rocul+c • To<+Rocul+ nhnhv • nhnhvftn+inn in r. · Obiectl !t.chart JltTtino< • flhiort' File 1.~ I I ChartOutput MessaploxOutput FileOutput

f+DisplayResul ts () +DisplayResul ts () +DisplayResul ts ()

Figure A-3. UML static structure representation ofhamess architecture

Conclusion

The .NET Framework provides a new Ievel of ease in developing software solu• tions. An extensible performance-testing harness was developed using the .NET Framework that allows the comparative and absolute execution speed of various routines to be tested and reported in a robust and consistent manner. The per• formance-testing harness is fully extensible and will support test execution for a wide variety of scenarios.

262 Index

Symbols Anakrino, 15 AndAlso keyword (VB .NET), 90 # ofCCWs, 210 ApartmentState property, Thread dass, # ofmarshalling counter, 210 204 # of Stubs, 210 AppDomain dass, System namespace #define, switching locks, 155 AppendPrivatePath method, 214 #pragma unmanaged code blocks, 95 Createlnstance method, 223 .NET CLR LocksAndThreads perfor• GetCurrentThreadld method, 159 mance object, 159 Append method, StringBuilder dass .NET Framework string conversion, 52 error handling model, 121 AppendFormat method, StringBuilder Framework Ubrary dass internalcall methods, 12 string conversion, 52 MSIL Disassembler, 13 AppendPrivatePath method, performance issues AppDomain dass, 214 introduction, 1 Application Center Test. See ACT material covered, 2 AQtime .NET profiler, 245 real-time operation, 5 arithmetic code, checking with CLR, 228 support for encryption, 138 Array dass, System namespace, 63 .NET Memory object, 102 Copy method, 67 .NET Memory Profiler, 118, 246 IUst.Contains, 63 .param statements (VB .NET), 94 implemented at runtime, 63 I clr switch, 95 implements collection dasses, 71 /optionstrict compiler command-line initialization, 65 option (VB .NET) Length property, 64 late binding, 93 reetangular vs. jagged arrays, 64 /removeintchecks compiler switch, 94 Reverse method, 57 /unsafe command line switch, 203 synchronization, 66 _gc keyword (C++), 96 SyncRoot property, 66 pin keyword (C++), 116 unsafe array access, 66 - dedaring and allocating a String ArrayUst dass, System.Collections object, 96 namespace, 69 . _finally keyword, 122 providing strongly typed collections, 72 A synchronization techniques, 77 Synchronized method, 66 Abort method, Thread dass, 259 ToArray method, 63 ThreadAbortException thrown, 124 arrays AcquireReaderLock method, initialization, 65 ReaderWriterLock dass, 154 string reversal method, 57-58 AcquireWriterLock method, synchronization,66 ReaderWriterLock dass, 154 Visual Basic .NET, and, 91 ACT (Application Center Test), 18, 248 ASP.NET Active Template Ubrary. See ATL. applications use domain-neutral address collision, avoiding, 216 loading, 221 AllocateNamedDataSlot method, server garbage collection, 103 Thread dass, 150 assernblies Allocation Profiler tool, 118 loading behavior working with managed heap, 243 multiple module assemblies, 218 AllacHGlobal method, Marshai dass strongly named assemblies, 218 copying managed code into unman• locating referenced assemblies, 214 aged memory, 115 263 Index

setting base address, 216 designing benchmarks, 22 unloading, 222 introduction, 10 Assembly dass, System namespace strengths and weaknesses, 10 Createlnstance method, 233 uses, 11 Assert attribute, 136 blittable data types, conversion require• AsyncCallback delegate ments, 196 asynchronaus method calls, 186 Boolean logic, Visual Basic .NET, 90 ATL (Active Template Library), 117 boxing, 44 AutoResetEvent dass, System.Threading BufferedStream dass, System.IO name• namespace, 148 space, 164, 169, 170

B c background initialization, example, 33 C style DLLs base address relocation scheme, 216 P/Invoke supports, 195 Base dass C# SecondsSinceMidnight method, 210 == operator·, 49 Beep function, 195 BeforeFieldlnit type attribute, 28 BeforeFieldlnit type attribute checked and unchecked arithmetic timing of static constructor, 28 code, 229 Beginlnvoke method, Control dass, 185 compared to J#, 99 benchmark test harness, 18, 249 finally keyword, 122 architectural summary, 261 fixed statement, 67 common design pitfalls, 22 foreach statement, 73, 76 comparing performance, 249 is keyword, 98 implementation of tests, 250 lock statement, 66 problems with tests, 251 performance features, 85-86 features, 19 performance issues, 97 string emptiness checks, 19 setting base address of assemblies, implementing, 252 217 delegate design, 255 stackalloc keyword, 83 function invocation, 252 String alias, 47 function ordering, 253 support for exception handlers, 122 result analysis and presentation, throwing exceptions, 128 259 unsafe keyword, 67 setup, deanup, and test result using directive, 73, 105 rejection, 255 variable initialization, 27 test execution, 258 caching channel sink, implementing, binary equality, string comparison, 48, 189 51 calledFromDisposeMethod parameter BinaryFormatter dass, Dispose method, IDisposable inter- System.Runtime.Serialization. face, 104 Formatters.Binary namespace, 17 4, 176 calli instruction, 202 BinaryReader dass, System.IO canonical instances, 30 namespace CAO (client-activated objects) characteristics, 167 lifetime management, 183 BinaryWriter dass, System.IO name• performance charateristics, 184 space case-insensitive comparisons, 51 characteristics, 167 Catch When statement (VB .NET), 122 BitArray dass, System.Collections Changeahle String Param test namespace, 69 nonblittable parameters, 196 BitVector32 dass, ChangeableStringParamUnsafe proto• System.Collections.Specialized name• type space, 69 converting unmanaged code, 197 black-box technique Char structure, System namespace, 53 assessment of performance, 2 GetHashCode method, 43 benchmark test harness, 18

264 Index character sets security model problems with operating systems, assemblies, 134 201 permissions, 132 CharEnumerator class stack walks and permission Current property, 53 demands, 136 CharSet property, Dlllmport class validation and verification during Auto enumeration value, 201 loading, 133 checked arithmetic code, 229 static constructors, 28 class constructors, 27 type design and implementation, 25 static constructors, 28 types exposing Equals method, 38 class encapsulation, 31 unmanaged interfaces, 226 performance-oriented design pat• code optimization, controversy of, 3 terns, 32 code profilers, performance problern properties, 31 solving, 238 cleanup functions code rules, performance problern defining for benchmark test harness, solving, 246 255 CodeAccessPermission class CLR (Common Language Runtirne) Assert method, 134 checked arithmetic code, 228 Deny method, 134 truncation and looping, 229 Collect method, GC class, 108, 156 class constructors, 27 alternative to IGCThreadControl, 156 debug symbols, 245 Collection type, .Visualßasic excecution interrupted, 123 assembly, 92 exception-based model, 89 using like Arraylist, 92 performance issues, 121 CollectionBase class, System.Collections garbage collector, 101 namespace, 69 mark-and-compact algorithm, 101 collections workstation and server versions, characteristics of classes, 71 102 enumeration, 73 headersettings,213 hash codes distribution, 78 inlining, 225 namespaces, 63 interacting with the unmanaged side, performance, 2 228 stack allocation, 83 interface implementation, 35 strong typing, 72 Interop object, 241 synchrorüzation,76 interoperability marshalling, 195 Visual Basic .NET, 91 loader compared to Wm32 loader, COM 214 avoiding COM-generated exceptions, loading behavior, 215 206 JIT compilation, 223 DLLs, COM Interop supports, 195 loader optimizations, 221 error translation, 206 multiple module assemblies, 219 interface implementation, 35 relocations, 215 Interop, 12 strongly named assemblies, 218 unmanaged code interoperability, unloading assemblies, 222 195 managed application memory usage, lifetime management, 204 231 loading COM objects, 203 managing, 226 marshalling objects between COM optional parameters not supported apartments, 204 by, 94 support in .NET, 203 process initialization, 213 command-line utility locating referenced assemblies, MSIL Disassembler, 13 214 Common Language Run time. See CLR protected blocks performance issues, Compare method, String class 124 Culturelnfo dass and, 50 real-time functionality and, 5 performance issues, 51 string comparison, 50

265 Index

comparisons, unfair data transmitters, MBV objects, 180 common pitfalls in benchmark data variables design, 23 populating with static constructors, compiler-generated intemed string, 54 28 CompileToAssembly method, Regex DataManager type dass, 59 exposing as singlecall SAO, 187 compressed files, support for, 171 DataReader dass, System.Data name• Compuware DevPartner Profiler space Community Edition profiler, 238 compared to DataSet, 249 sample run, 239 DataSet dass, System.Data namespace concurrentcollection compared to DataReader, 249 overriding, 103 DateTime structure, System namespace workstation garbage collector, 102 accuracy of timing under a second, Configuration Properties, Build page, 251 231 Now method, 22 Configure method, debug build compared to release build, RemotingConfiguration dass, 187 230 Constant String Param Ansi test DebugBreak function, 16 nonblittable parameters, 196 DebuggableAttribute dass Control dass IsJITOptimizerDisabled property, 231 Beginlnvoke method, 185 IsJITTrackingEnabled property, 231 Invoke method, 185 Debugging unmanaged CLR interfaces, Convert dass, System namespace 226 Tolnt64 method, 44 debugging symbols, unmanaged CLR Copymethod interfaces, 227 Array dass, 67 Decimal type and high-precision Marshai dass, 115, 199 numerical operations, 230 CopyFile function, 201 dedarative synchronization options, CorRuntimeHost COM dass 145 interacting with CLR, 228 decompilers, 15 Count property, ICollection interface, 71 Decrement method, Interlocked dass, CPU usage, observing, 235 148 CreateFile function, 168 delayed loading, CLR loader, 214 Createlnstance method Delegate dass, System namespace AppDomain dass, 223 GetlnvocationList method, 254 Assembly dass, 233 Remave method, 111 CRLcontrol Demand attribute, 136 unmanaged CLR interfaces, 227 Derived dass cross-application domain SecondsSinceMidnight method, 210 data access, 179 deserialization, 173 memory access, 221 destructors, 31 cross-technology comparisons, compared to finalizers, 106 controversy of, 3 deterministic finite automaton. See cryptography, 138 DNFA Culturelnfo dass, System.Globalization DFA (deterministic finite automaton), namespace, 50 58 Current property DictionaryBase dass, CharEnumerator dass, 53 System.Collections namespace, 69 IEnumerator interface, 75 Directory dass, System.IO namespace custom attributes, 225 characteristics, 167 custom value types and J#, 99 Directorylnfo dass, System.IO name• space characteristics, 167 D DiskMon tool data compression, sink chains, 188 factors affecting 10 performance, 164 data tlow analysis, 179 data managers, MBR objects, 180

266 Index

Dispose method, IDisposable interface, ValueType dass, 38 105-106, llO complexity of, 38 calledFromDisposeMethod parame• error handling, Visual Basic .NET, 89 ter, 104 execution interrupted, 123 freeing unmanaged resources, 104 exception handlers, 122 distributed systems exceptions, 121 data flow analysis, 179 coding to avoid, 127 remoting, 2 execution interrupted, 123 Dlllmport attribute, 225 monitoring, 129 CharSet property, Auto enumeration protected blocks, 122 value, 201 rethrowing, 125 domain-neutralloading throwing, 127 access to static variables, 221 Exchange method, Interlocked ASP.NET applications use, 221 dass, 148 Double dass, System namespace, 72 ExecutionEngineException dass double hashing, 79 thrown by runtime, 124 double initialization Exit method, Monitor dass poor practice, 27 manual synchronization, 146 dynarnically generated interned synchronization performance, 14 7 string, 54 explicit user-defined type conversion, 36 E element accessor functions, F collections, 71 FAT file systems, 173 Empty property, String dass, 19, 30 fault handlers, 122 string emptiness checks, 53 File dass, System.IO namespace empty string literal (), 19 characteristics, 167 encryption, 138 SetAttributes method, 170 key length and safety, 140 FILE_ATTRlBUTE_NORMAL flag Enter method, Monitor dass creation of FileStream object, 169 manual synchronization, 146 FILE_FLAG_OVERLAPPED flag enterprise tools, 247 creation ofFileStream object, 169 distributed profilers, 247 FILE_FLAG_SEQUENTIAL_SCAN hint load generation tools, 248 creation of FileStream object, 168 Visual Studio Analyzer, 24 7 Fileinfo dass, System.IO namespace enumeration characteristics, 167 collections FileMon tool loop invariants, 76 factors affecting 10 performance, 164 loop terrnination, 76 FileStream dass, System.IO namespace, performance issues, 7 4 165, 168 strings, 53 CanRead property, 127 techniques for visiting each char• characteristics, 166-167 acter, 53 constructors, 168 equality checks, 191 FileSystemWateher dass, System.IO equalizer test suite, unrelated namespace, 173 common pitfalls in benchmark Finalizations, factors affecting perfor• design, 22 mance, 106 Equals method finally handlers, 122 Object dass, 38, 191 finally keyword (C#), 122 inherited by String, 48 fixed statement (C#) using the is operator, 40 unsafe array access, 67 overriding for all CLR types, 38 For Each ... Next statement, 73 String dass foreach statement (C#), 73, 76 binary equality, 48 Format method, String dass compared to ReferenceEquals, 55 string conversion, 52

267 Index

formatters and channels, 183 hashcodes Freelibrary function, 202 distribution options, 81 FreeNamedDataSlot method, Thread String class distribution example, 78 class, 150 Hashtable class, System.Collections namespac~69, 191 double hashing, 79 G storing request-response collection, garbage collection, 2 191 See also CLR, garbage collector and high-end machines performance test• GC class. ing,6 memoryusage optimization, 110 HRESULT, COM error translation, 206 weak references, 112 HttpChannel class, 180 pinning, 115 interoperability, 182 unmanaged CLR interfaces, 227 SOAP formatter, 183 unmanaged resources, 104 supported by ns, 187 generic and specific, 107 HybridDictionary class, GC class, System namespace, 102 System.Collections.Specialized Collectmethod, 108, 156 namespace, 70 SuppressFinalize method, 104 hyper-threading, 151 WaitForPendingFinalizers method, 108 GCHandle class I avoiding pinningTarget property, 116 IAsyncResult interface gcroot template (C++) asynchronaus method calls, 186 avoiding pinning, 97, 116 IClientChannelSink interface generic unmanaged resources, 107 defining a sink, 189 garbage collection, 108 ProcessMessage method, 189 GetAvailableThreads method, ICollection interface, ThreadPool class, 158 System.Collections namespace GetCurrentThreadld method, Count property, 71 AppDomain class, 159 SyncRoot property, 76 GetEnumerator method IComparer interface, 192 IEnumerable interface, 73 ICorConfiguration interface String class, 53 SetGCHostControl method, 156 GetHashCode method ICorThreadPool interface Char structure, 43 thread pooling, 159, 227 implementation guidelines, 43 ID Thread counter, 159 Object class, 191, 233 IDisposable interface implementation, 41 compared to ReleaseComObject ValueType class, 40 method,205 implementation, 41 Dispose method, 104-106, 110 Getlnvocationlist method, Delegate IEnumerable interface, 53 class, 254 explicit interface implementation, 75 GetNamedDataSlot method, Thread GetEnumerator method, 73 class, 150 implementing by String class, 47 GetProcAddress function, 202 IEnumerator interface GetType method, Object class, 4Q-41 Current property, 75 get_Current method, IEnumerator inter• get_Currentmethod,75 face, 75 IFormatProvider interface grey box investigation, 17 culturally specific data, 52 GUI application mode, MSIL IFormattable interface Disassembler, 14 string formatting, 52 use of implementing type, 52 IGCHost interface, 228 H IGCHostControl interface HandleCollector class, System RequestVirtualMemlimit method, namespace, 109 117

268 Index

SetGCHostControl method, 117 InvalidCastException dass, 127 setting maximum ceiling for process performing type checks before cast- memory usage, 227 ing prevents, 40 · IGCThreadControl interface Invoke method, Control dass, 185 thread suspension, 156, 227 InvokeMember method, Type dass, 233 IHashCodeProvider interface, 81, 192 10 performance IIS hosting factors affecting, 164 ASP.NET and, 188 reading and writing to disk, 166 performance issues, 188 sparse, compressed, and memory- remote objects, 187 mapped files, 170 support for HttpChannel, 187 target platforms, 172 IJW (It JustWorks), 95 is keyword (C#), 98 mixing of managed and unmanaged ISerializable interface, 173 code, 208 compared to using reflection, 17 4 lldasm.exe, 13 marshal-by-value objects and, 179 See also MSIL Disassembler. IServerChannelSink interface immutability defining a sink, 189 String dass, 4 7 ProcessMessage method, 189 Stringßuilder dass, 47 isinst instruction, 98 implicit user-defined type conversion, !sintern method, String dass, 54 36 lsJITOptimizerDisabled property, INamingContainer interface, DebuggableAttribute dass, 231 System.Web.UI namespace, 226 IsJITii"ackingEnabled property, Increment method, Interlocked dass DebuggableAttribute dass, 231 compared to Monitor lock, 148 IsReEntrant property, lndexOf method, String dass SynchronizationAttribute dass, 145 calling asynchronously, 186 IndexOutOffiangeException dass, 76 InitializeArray method, RuntimeHelpers J dass, 65 J# inlining compared to C#, 99 MSIL and, 225 performance issues, 99 preventing, 225 JDK übraries, 99 lnt32 dass, System namespace, 63 ToString implementation, 99 C# wrapper for, 72 jagged arrays, 64 MaxValue method, 81 Java Hotspot technology, 225 MinValue method, 81 JDK übraries unsafe array access, 67 performance issues, 99 interface implementation, 34 JIT (Just-In-Time), 5 interferences, unrelated inlining, 225 common pitfalls in benchmark interface implementation, 35 design, 23 leveling role in language Interlocked dass, System.Threading performance, 87 namespace loading behavior, 223 methods, 148 performance advantage, 224 Intern method, String dass, 54 producing MSIL-to-native offset internpool map,231 examples, 54 string manipulation, 54 internalcall method attribute K Array.Copy implementation, 67 kernel32.dll lnternet_Zone permission, 133 Beep function, 195 interoperability CopyFile function, 201 marshalling, 195 QueryPerformanceCounter conversion requirements oftypes, function, 259 196 monitoring, 210

269 Index

L M laggard, ll O-ll1 managed applications language specifics memory usage, 231 performance issues, 2, 85 ManagedC++ selection, 2 blittable pararneters, 209 Visual Basic .NET, 87 interoperability, 208 lapsed listener, llO loading behavior example, lll relocations, 215 late binding performance features, 85 Visual Basic .NET, 93 performance issues, 95 layered strearns, 165 support for exception handlers, 122 IZW compression algorithm, 165 _finally keyword, 122 lazy initialization, 28 managed heap example,32 generations, 101 Length property reference types allocation, 25 Array dass, 64 manual synchronization, 146 String dass, 19, 30 ManualResetEvent dass, string emptiness checks, 53 System.Threading narnespace, 148 limbo, 1ll mark-and-compact algorithm example, ll1 CLR garbage collector, 101 lingerer, ll O-ll1 marker interfaces, 225 LlllldDemands,137 Marshai dass, linked lists, 79 System.Runtime.lnteropServices narne• UstDictionary dass, space, 83 System.Collections.Specialized narne• converting space, 70 pointers to value types or strings, enumerators, 7 4 199 LoaderOptimizationAttribute dass unmanaged code, 197 specifying use of single domain direct memory manipulation, 94 assembly loads, 221 methods loading behavior AllocRGlobal method, ll5 JIT compilation, 223 Copy method, ll5, 199 loader optimizations, 221 PrelinkAllmethod,202 multiple module assemblies, 218 PtrToStringAnsi method, 200 relocations, 215 ReleaseComObject method, 205 unloading assemblies, 222 Write method, ll5 LoadUbrary function, 202 marshal-by-reference. See MBR. lock contention reducing, 150 marshal-by-value. See MBV. lock statement (C#), 66 MarshalByRefObject, System narne• synchronization performance, 147 space, 180 thread safety, 146 using SynchronizationAttribute, 145 logical equality MarshalFromByteArray sarnple string comparison, 48, 51 converting IntPtr to System.String loiterers, llO object, 200 loop invariants Math dass, System narnespace enumeration and collections, 76 using a hidden constructor, 28 loop termination MaxValue method, Int32 dass, 81 enumeration and collections, 76 MBR (marshal-by-reference) objects, looping and arithmetic code, 229 180 low-end machines performance asynchronous method calls, 186 testing, 6 data managers, 180 low-level execution control MBV (marshal-by-value) objects Visual Basic .NET, 94 cross-application domain data IZW compression algorithm, 165 access, 179 data transmitters, 180

270 Index

memory MS Product Support Services. See PPS. handling exhaustion gracefully, 117 MSCHART ActiveX control monitaring tools, 118 implementing result presentation for diagnosing problems, 243 charts,260 profilers, 243 MSIL (Microsoft Intermediate usage optimization, 110-113 Language) weak references, 112 dissassemblers and decompilers, 12 object recycling, 113 inlining,225 Memory Usage column (Task MSIL Disassembler Manager), 237 See also lldasm.exe. memory-mapped files, 172 /OUT command-line switch, 29 MemoryStream dass, System.IO operation modes, 13 namespace command-line utility, 13 characteristics, 166 Gill application mode, 14 message box output MSIL instructions implementing result presentation, calli instruction, 202 261 causing an overflow, 229 method modifiers isinst instruction, 98 performance considerations, 37 localloc instruction, 83 MethodlmplAttribute dass, newarr System.Int32, 63 System.Runtime.CompilerServices rethrow instruction, 123, 125 namespace throw instruction, 123, 125 dedarative synchronization, 145 MSIL-to-native offset map Microsoft Intermediate Language. See produced by JIT, 231 MSIL. MTAThreadAttribute dass, 204 Microsoft.VisualBasic assembly multidimensional arrays backwards compatibility, 88 iteration performance, 64 string equality, 88 multiple module assernblies Collection type, 92 creating, 219 implementation of features without loading behavior, 218 CLR support, 88 problems with splitting, 219 late binding, 93 multithreading, pattems supported, 143 Microsoft.VisualBasic namespace Mutex dass, System.Threading name• Strings dass, 49 space Microsoft.VisualBasic.Compatibility.dll equivalent to Wm32 mutex, 148 Visual Basic .NET backwards com• lock compared to Monitor lock, 148 patibity, 87 My_Computer_Zone permission, Microsoft.VisualBasic.dll 133-134 Visual Basic .NET backwards com- patibity, 87 MinValue method, Int32 dass, 81 N Monitor dass, System.Threading name• NameObjectCollectionBase dass, space,66, 77 System.Collections.Specialized name• equivalent to Win32 critical section, space, 70 148 tool Methods loading behavior, 215 Enter method, 146 benefits, 224 Exit method, 146 .NET See .NET Pulse method, 151 NetworkStream dass, Wait method, 151 System.Net.Sockets namespace, 169 objects shared across threads, 144 newarr System.Int32 MSIL instruction, switching locks with 63 ReaderWriterLock dass, 154 NFA (nondeterministic finite automa• monitaring ton), 58 exceptions, 129 Ngen.exe tool, loading behavior, 215 memory,118 remoting, 193

271 Index

nonblittable data types optional parameters conversion requirements, 196 Visual Basic .NET, 94 nondeterministic finite automaton. See op_Equality method, String dass NFA. MSIL representation of C# operator noninterned string, 54 ==,49 NormalizedTestDuration attribute string emptiness checks, 53 testtun element, 22 OrElse keyword (VB .NET), 90 notification, unmanaged CLR inter• OSI protocol stack faces, 226 layers defined, 181 NotSerialized attribute, 174 OutOfMemoryException dass, 117,243 Now method, DateTime structure, 22 thrown by runtime, 124

0 p 0(1) complexity P/Invoke, 12 collection operations, 63 character sets, 201 O(n) complexity manual marshalling performance collection operations, 63 advantage, 198 Object dass, System namespace, 38 marshalling data to managed types, Equals method, 48, 191 199 GetHashCode method, 41, 191,233 security attributes, 202 GetType method, 40-U unmanaged code interoperability, ReferenceEquals method, 55 195 object lifetime management, 101 unmanaged DLL loading and See also CLR, garbage collector. unloading, 201 object pooling, 113 PE (Portable Executable) format, 213 object recycling, 113 data contained in headers, 214 objects PerfMon. See Windows System Monitor. allocation and population, 27 performance and development boxing and unboxing, 44 process,3 canonical instances, 30 categories of performance priorities, dass constructors, 27 4 dass encapsulation, 31 developer responsibilities, 7 destructors, 31 test environment and practices, 6 interface implementation, 34 performance critical/real time method modifiers, 37 development category, 5 static constructors, 28 performance insensitive development user-defined type conversion, 36 category, 4 preventing creation, 28 performance investigation Obsolete attribute, System black-box technique, 10 namespace, 225 defining precise questions, 9 On Error GoTo statement, 89 white-box technique, 10 On Error Resurne Next Statement, performance issues 89,246 C#,97 compared to try-catch block, 123 channels, 182 OneWay methods, remoting, 185 collection dasses, 71 Open System Interconnection. See OSI. strong typing, 72 operating systems collection operations, 63 problems with character sets, 201 Compare method, String dass, 51 optimized-away test cases comparing strings, 48 common pitfalls in benchmark cryptography and encryption, 138 design, 22 symmetric and asymmetric Option Compare functionality comparison, 139 compared to C# operator ==, 49 development process, 3 Option Strict Offoption (VB .NET) performance priorities, 4 late binding, 93 domain-neutralloading, 221 enumerators and collections, 74

272 Index

exception handler efficiency, 122 process initialization, 213 exceptions, 121 locating referenced assemblies, 214 IIS hosting, 188 process memory usage, controlling, 117 J#, 99 ProcessMessage method JDK libraries, 99 IClientChannelSink interface, 189 language selection, 2 IServerChannelSink interface, 189 language specifics, 85 SoapServerFormatterSink class, 183 Visual Basic .NET, 87 Product Support Services, 246 loading behavior of strongly named profi.lers, 17 assemblies, 218 profi.ling unmanaged CLR interfaces, locating and fixing problems, 2 226 Managed C++, 95 Project Pages dialog object pooling, 114 setting base address of assemblies, pinning, 115 216 protected blocks, 124 properties reflection, 233 achieving encapsulation, 31 reversing strings, 56 protected blocks security and, 131 See also try blocks. stack walks, 136 handler efficiency, 122 string formatting, 52 handlers, 122 threading, 143 PtrToStringAnsi method, Marshai unsafe array access, 67 dass, 200 Performance Monitor. See Wmdows public key encryption, 139 System Monitor publication performance problern solving, 235 unmanaged CLR interfaces, 226 below the source code, 244 Pulse method, Monitor dass, 151 code profi.ler, 238 compared to Sleep method, Thread code rules, 246 class, 152 enterprise tools, 24 7 memory profilers, 243 PPS,246 Q Task Manager, 235 QueryPerformanceCounter third-party tools, 245 function, 19, 259 Wmdows System Monitor, 240 QueryPerformanceFrequency performancesensitive development cat• function, 19 egory, 4 Queue class, System.Collections permission asserts namespace, 70 dedarative, 138 QueueUserWorkltem method, permission demands, 136 ThreadPool dass, 157 imperative, 138 PermissionSet dass multiple permissions within method, R 137 race conditions PIA (Primary Interop Assembly), 203 synchronization techniques and, 78 pinning Random dass, System namespace, 254 heap fragmentation, 115 ReaderWriterLock dass, performance issues, 115 System.Threading namespace, 154 Portable Executable format. See PE. AcquireReaderLock method, 154 PPS (Product Support Services), 246 AcquireWriterLock method, 154 PielinkAll method, Marshai dass, 202 allowing easy switching with Monitor Primary Interop Assembly. See PIA. lock, 154 PrimarylnteropAssemblyAttribute dass ReadFile function, 168 identifying PIA, 203 ReadOnlyCollectionBase dass, private key encryption, 139 System.Collections namespace, 69 PrivatelmplementationDetails type real-time operation array initialization, 65 Wmdows, NT, .NET and, 5

273 Index

Rehase tool RemotingConfiguration dass base address relocation scheme, 216 Configure method, 187 reetangular arrays, 64 Remove method, Delegate dass, 111 ReDim functionality (VB .NET), 92 RequestVirtualMemLim.it method, ReDim Preserve functionality (VB IGCHostControl interface, 117 .NET), 92 resource contention, thread reference equality, 38, 191 synchronization, 153 reference types result handle HRESULT implementing GetHashCode COM error translation, 206 method,41 rethrow instruction, 123, 125 introduction, 25 rethrowing exceptions, 125 overriding the Equals method, 38, 40 uses, 126 referenced assernblies Reverse method, Array dass Iocating, 214 reversing strings, 57 ReferenceEquals method, Object dass reversing strings compared to String.Equals, 55 array-based reversal method, 58 reflection, 232 array-based string reversal method, compared to using ISerializable 57 interface, 174 fastest methods, 57 object pooling, 113 techniques, 56 performance issues, 233 RijndaelManaged dass Regex dass, symmetric encryption, 139 System.Text.RegularExpressions name• Rotor, 16 space, 59 round-tripping an assembly CompileToAssembly method, 59 problems, 29 Regexüptions enumeration, RSACryptoServiceProvider dass System.Text.RegularExpressions name• asymmetric encryption, 139 space, 61 RunTests method, TestRunner object, 20 RegExToAssm dass, RuntimeHelpers dass, System. Text.RegularExpressions name• System.Runtime.CompilerServices space, 60 namespace RegisterWaitForSingleObject method, InitializeArray method, 65 ThreadPool dass, 157 RegNotifyChangeKeyValue function, 157 regular expressions, 58 s example, 59 SAO (server-activated objects) processing engines, 58 dealing with stateless nature, 184 Regex dass, 59 lifetime management, 183 RegExToAssm dass, 60 scalability design and costs, 5 release build compared to debug Scribble sample application build, 230 benefits of Ngen usage, 224 ReleaseComObject method, Marshai SecondsSinceMidnight method, Base dass, 205 dass, 210 compared to IDisposable, 205 SecondsSinceMidnight method, Derived remoting, 179 dass, 210 calling methods, 185 Secure Sockets Layer. See SSL. asynchronously, 186 security, 131 OneWay methods, 185 CLR security model, 132 channel selection, 180 cryptography and encryption, 138 formatters, 183 design decisions, 131 distributed systems, 2 monitoring, 140 IIS hosting, 187 unsafe array access, 68 monitoring, 193 SerializableAttribute dass, 173 object activation, 183 marshal-by-value objects and, 179 sink chains, 188 serialization, 163, 173 Remoting Probe tool custom optimization techniques, 175 monitaring remoting, 193 formatter options, 176

274 Index

Serializationlnfo dass stack allocation implementing lazy deserialization, collections, 83 175 value types allocation, 25 server garbage collector, 102 Visual Basic .NET and, 83 server-side application Stack dass, System.Collections defining performance, 5 namespace, 70 SetAttributes method, File dass, 170 stackwalks SetData method, Thread dass, 150 performance impact, 136 SetFileAttributes function, 171 suppressing, 136 SetGCHostControl method stackalloc keyword (C#), 83 ICorConfiguration interface, 156 StackFrame dass, System.Diagnostics IGCHostControl interface, 117 namespace, 225 Shared Source Common Language StackTrace property, Exception object, Infrastructure. See SSCLI. 125 single domain assembly loads state-estranged methods, 37 applications use, STAThreadAttribute dass, 204 221 static constructors singlecall objects, 183 populating data variables, 28 singleton objects, 183 timing, 28 sink chains, 188 Web services and, 28 collections, equality and serializa- static variables, accessing tion, 191 domain-neutralloading, 221 implementing a channel sink, 189 StrComp method, Strings dass, 49 uses, 188 Stream dass, System.IO namespace, using the channel sink, 192 164-165, 170 SkipVerification perrnission, 134 characteristics, 166 executing nonverifiable code, 221 StreamingContext dass, 175 unsafe array access, 67 StreamReader dass, System.IO Sleep method, Thread dass, 151 namespace compared to SpinWait method, characteristics, 167 Thread dass, 153 StreamWriter dass, System.IO compared to Wait/Pulse methods, namespace 152 characteristics, 167 SoapFormatter dass, String alias System.Runtime.Serialization. C#and,47 Formatters.Soap namespace, 17 4 String dass, System namespace formatter options, 176 CLRand,47 SoapServerFormatterSink dass compared to ProcessMessage method, 183 System.Text.StringBuilder, 8 SortedUst dass, System.Collections converting from Unicode to ANSI, namespace, 70 196 sparse files, creating and accessing, 171 efficiency of appending characters, specific unmanaged resources, 107 56 garbage collection, 107 hash code distribution example, 81 SpinWait method, Thread dass immutability, 47 compared to Sleep method, Thread implements IEnumerable interface, dass, 153 47 SQLServer Methods benchmark test harness and, 251 Campare method, 50 SSCLI (Shared Source Common Equals method, 48, 55 Language Infrastructure), 12, 16 Formatmethod,52 SSL (Secure Sockets Layer) GetEnumerator method, 53 symmetric session key-exchange IndexOf method, 186 technique, 139 Intern method, 54 !sintern method, 54 op_Equality method, 49, 53 ToCharArray method, 57

215 Index

Properties StringWriter dass, System.IO Empty property, 19, 30 namespace Length property, 19, 30, 53 characteristics, 167 string equality and VB .NET, 88 Strang Name Tool thread safety, 144 generating key pairs, 218 string comparison, 48 strongly named assernblies Campare methods, 50 loading behavior, 218 equality checks in C# and VB .NET, StrReverse method, Strings dass, 57 49 SuppressFinalize method, GC dass, 104 Equals method, 51 reduces performance impact of string conversion finalization, 107 comparison of methods, 53 SuppressUnmanagedCodeSecurity string emptiness checks, 19 Attribute dass, System.Security techniques, 53 namespace,202,208 string equality, VB .NET and, 88 suppressing stack walks, 136 string formatting, 52 synchronization of collections, 76 IFormattable interface, 52 synchronization primitives, 148 ToString methods, 52 SynchronizationAttribute dass, string manipulation, 47 System.Runtime.Remoting.Contexts comparison, 48 namespace emptiness checks, 53 dedarative synchronization, 145 enumeration, 53 IsReEntrant property, 145 formatting, 52 Synchronized method immutability, 47 ArrayList dass, 66, 144 intern pool, 54 dasses in System.Collections regular expressions, 58 namespace, 77 reversing strings, 56 and thread safety, 144 techniques for visiting each synchronization performance, 147 character, 53 SyncLock statement (VB .NET) StringBuilder dass, System. Text synchronization performance, 147 namespace, 196 thread safety, 146 Append method, 52 SyncRoot property, ICollection interface compared to System.String, 8 synchronization, 76 efficiency of appending characters, systemmonitaring utilities, 17-18 56 System namespace immutability, 47 AppDomain dass, 214 mutability, 55 Array dass, 57, 63 reversing strings, 57 Assembly dass, 233 setting number of characters to be Char structure, 43 stored, 56 Convert dass, 44 ToString method, 55, 57 Delegate dass, 111, 254 StringCollection dass, Double dass, 72 System.Collections.Specialized GC dass, 102, 108 namespace, 69 HandleCollector dass, 109 StringDictionary dass, Int32 dass, 63, 81 System. Collections.Specialized MarshalByRefObject dass, 180 namespace, 70 Math dass, 28 StringReader dass, System.IO Object dass, 38, 48 namespace Obsolete attribute, 225 characteristics, 167 Random dass, 254 strings, Visual Basic .NET, 88 String dass, 8, 19, 30, 48, 186 Strings dass, Microsoft.VisualBasic TimeSpan structure, 259 namespace ValueType dass, 38 StrComp method, 49 WeakReference dass, 112 StrReverse method, 57 System.Collections namespace, 63 ArrayList dass, 69 BitArray dass, 69

276 Index

classes, 68 unmanaged memory allocation, 110 characteristics, 71 System.Runtime.Remoting.Contexts CollectionBase class, 69 namespace DictionaryBase class, 69 SynchronizationAttribute class, 145 Hashtable class, 69, 79, 191 System.Runtime.Serialization. ICollection interface, 71 Formatters.Binary namespace Queue class, 70 BinaryFormatter class, 17 4, 176 ReadOnlyCollectionBase class, 69 System.Runtime.Serialization. Sortedlist class, 70 Formatters.Soap namespace Stack class, 70 SoapFormatter class, 17 4, 176 Synchronized method, 77 System.Security namespace System.Collections.Specialized name• SuppressUnmanagedCodeSecurity space, 63 Attribute class, 202 BitVector32 class, 69 System. Text namespace classes, 68 specialized string processing, 4 7 characteristics, 71 StringBuilder class, 8, 47, 55, 196 element accessor functions, 71 UnicodeEncoding class, 200 HybridDictionary class, 70 System.Text.RegularExpressions name• üstDictionary class, 70, 74 space NameObjectCollectionBase class, 70 Regex class, 59 StringCollection class, 69 RegexOptions enumeration, 61 StringDictionary class, 70 RegExToAssm class, 60 System.Data namespace regular expressions, 58 DataReader class, 249 System.Threading namespace DataSet class, 249 AutoResetEvent class, 148 System.Diagnostics namespace Interlocked class, 148 StackFrame class, 225 ManualResetEvent class, 148 System.Globalization namespace Monitor class, 66, 77 Culturelnfo class, 50 ReaderWriterLock class, 154 System.IO namespace, 163 synchronization primitives, 148 BufferedStream class, 169 Thread class, 259 Classes ThreadAbortException class, 259 characteristics, 166 ThreadPool class, 157 types, 164 ThreadStart delegate, 259 FileStream class, 127, 168 Timer class, 158 FileSystemWatcher class, 173 System.Web.UI namespace hard disk access speed, 163 INamingContainer interface, 226 layered streams, 165 System.Wmdows.Forms assembly reading and writing to disk, 166 managing GDI resources, 109 Stream class, 165 Wm32 functionality, 163 System.Net.Sockets namespace T NetworkStream class, 169 target environment System.Retlection.Emit namespace performance testing, 6 allows use of special-purpose code, Task Manager 86 columns, 237 supports runtime generation of CLR• performance problern solving, 235 targeting assemblies, 213 TcpChannel class, 180 System.Runtime.CompilerServices binary formatter, 183 namespace performance considerations, 182 MethodlmplAttribute class, 145 tcpTrace tool RuntimeHelpers class, 65 monitaring remoting, 193 System.Runtime.InteropServices test environment and practice rules, 6 namespace test methods, defining with delegates, OllimportAttribute class, 195 19 excecution interrupted, 124 Marshai class, 83, 94, 115, 197, 205

277 Index

test runs, overly short ThreadinterruptedException dass, 124 common pitfalls in benchmark ThreadPool class, System. Threading design, 23 namespace, 157 TestResultGrp object, 20 GetAvailableThreads method, 158 testrun element modifying process-wide thread pool, NormalizedTestDuration attribute, 158 22 queued work example, 157 TestRunner object QueueUserWork:Item method, 157 RunTests method, 20 RegisterWaitForSingleObject method, TextReader dass, System.IO namespace 157 characteristics, 167 ThreadPriority property, Threaci dass, TextWriter dass, System.IO namespace 259 characteristics, 167 ThreadStart delegate, System.Threading Thread dass, System.Threading namespace, 259 namespace ThreadStaticAttribute dass, Abortmethod,259 System.Threading namespace ApartmentState property, 204 local storage support, 150 methods supporting local storage, throw instruction, 123, 125 150 throwing exceptions, 127 Sleep method, 151, 153 time slice, allocating to threads, 151 SpinWait method, 153 Timer dass, System.Threading name• ThreadPriority property, 259 space, 158 thread coordination TimeSpan structure, System namespace, worker threads, 148 259 thread locking Tlbimp tool, 203 thread synchronization, 153 ToArray method, Arrayüst dass thread pooling, 156 complexity of collection operation, modifying process-wide thread pool, 63 158 ToCharArray method, String dass thread safety reversing strings, 57 Array dass, 66 Tolnt64 method, Convert class collections and Synchronized testing conversion with and without method, 77 boxing, 44 dedarative synchronization, 145 ToString method, Object dass manual synchronization, 146 J# and, 99 pattems supported by CLR, 144 ToString method, StringBuilder dass, synchronization performance, 146 55-56 thread suspension reversing strings, 57 IGCThreadControl interface, 156 string conversion, 53 thread synchronization TI:ace dass resource contention and thread Writeüne method, 80 locking, 153 truncation synchronization primitives and arithmetic code, 229 equivalent to Wm32, 148 tryblocks thread coordination, 148 See also protected blocks. thread-local storage handlers, 122 support for, 150 try-catch block ThreadAbortException dass compared to On Error Resurne Next thrown by Abort method, Thread error handling, 123 dass, 124 performance issues, 124 ThreadAbortException dass, try-finally block, 105 System.Threading namespace, 259 performance issues, 124 threading, 143 type aliases (C#), 73 monitaring tools, 159 Type dass performance issues, 143 lnvoke~embermethod,233 synchronization, 143

278 Index type design introduction, 25 categories of type, 25 J# cannot customize, 99 CLR design pattems, 25 overriding the Equals method, 38 optimizing performance characteris• value-based equality, 191 tics, 2 Value'I'ype dass, System namespace, 38 Type library Importer Equals method, 40 /unsafe command line switch, 203 GetHashCode method, 40-41 type-filter exception handlers, 122 variable initialization TypeAttributes dass, 173 C#and,27 verification unmanaged CLR interfaces, 227 u VirtualAddress Dump. SeeVADUMP unboxing, 44 utility. UnicodeEncoding dass, System. Text Vrrtual Memory Size column (Task namespace Manager), 237 converting byte array to string, 200 virtual properties unit testing tools achieving encapsulation, 31 performance testing, 7 Visual Basic unmanaged C++ unstructured error handling model, compiler sets benchmark for perfor• 89 mance,87 Visual Basic .NET exceptions performance issues, 121 arrays and collections, 91 interface implementation, 34 backwards compatibility, 87 unmanaged code BeforeFieldlnit type attribute and, 28 interoperability, 195 Boolean logic, 90 COM lnterop, 195 Catch When statement, 122 P/lnvoke, 195 checked and unchecked arithmetic performance issues, 2 code, 229 unmanaged resources error handling, 89 cost offinalizations, 106 ForEach ... Next statement, 73 disposing of, 104 late binding, 93 generic and specific, 107 low-level execution control, 94 UnmanagedCode permission On Error Resurne Next error han- calling unmanaged code, 202 dling, 123 unsafe array access, 67 On Error Resurne Next functionality, performance benefits, 67 246 security issues, 68 optional parameters, 94 unsafe keyword (C#), 67 performance issues, 87 user-defined type conversion setting base address of assemblies, implicit and explicit, 36 217 user-filtered exception handlers, 122 stack allocation and, 83 using directive (C#), 73, 105 strings, 88 try-finally technique, 105 VisualC++ problems with round-tripping an assembly, 29 V Visual Studio .NET VADUMP utility, 119 automating round-tripping, 29 diagnosing memory problems, 243 Visual Studio .NET debugger managed applications memory not affected by build configuration, usage,232 230 value equality, 38 thread monitoring, 159 valuetypes x86 disassembly, 16 as parameters, 26 Visual Studio Analyzer, 247 boxing and unboxing, 44 equality checks implementation, 39 implementing GetHashCode method,41

279 Index w Wmdows API functions QueryPerformanceCounter function, Wait method, Monitor class, 151 19 compared to Sleep method, Thread QueryPerformanceFrequency func• class, 152 tion, 19 WaitCallback delegate object, 157 Wmdows Forms applications WaitForPendingFinalizers method, GC managed applications memory class, 108 usage,231 WaitOrTimerCallback delegate, 157 use of single domain assembly loads, WeakReference class, System name- 221 space . Wmdows NT real-time Operation, 5 creating and converting, 112 Wmdows System Monitor white-box technique .NET CLR LocksAndThreads perfor- assessment of performance, 2 mance object, 159 defining explicit goals, 11 .NET Memory object, 102 disassembles and decompilers, 12 factors affecting 10 performance, 164 decompilers, 15 monitaring exceptions, 129 introduction, 10 monitaring Interop, 210 strengths and weaknesses, 10 monitaring security, 140 uses, 11 performanceproblern solving, 240 profilers and system utilities provides data on .NET CLR memory, grey box investigation, 17 118 Rotor, 16 sample graph, 240 x86 disassembly, 16 writing custom counters, 242 Whittington, Jason, 16 WmRunner tool, 248 Wm32 functions worker threads CreateFile function, 168 multiple threads increases complex• DebugBreak function, 16 ity, 150 ReadFile function, 168 thread coordination, 148 RegNotifyChangeKeyValue function, workstation garbage collector, 102 157 concurrentcollection,102 SetFileAttributes function, 171 overriding, 103 WriteFile function, 168 Write method, Marshai class, 115 Wm32loader WriteFile function, 168 compared to CLR loader, 214 Writeüne method, Trace class, 80 loading behavior relocations, 215 Wm32 synchronization primitiv~s X equivalents in System.Threading namespace, 148 x86 disassembly Wm32-style DLLs complexity, 16 Pllnvoke supports, 195 XmlTextWriter class implementing Wmdows XML output result real-time operation, 5 presentation, 259

280 JOIN THE APRESS FORUMS AND BE PART OF OUR COMMUNI1Y. You'll find discussions that cover topics of interest to IT professionals, programmers, and enthusiasts just like you. II you post a query to one of our forums, you can expect that some ofthebest minds in the business-especially Apress authors, who all write with The Expert's Voice™-will chimein to help you. Why not aim to become one of our most valuable partic• ipants (MVPs) and win cool stuft? Here's a sampling of what you'll find:

DATABASES PROGRAMMING/BUSINESS Data drives everything. Unfortunately, it is. Share information, exchange ideas, and discuss any database Talk about the Apress line of books !hat cover soflware prograrnming or administration issuas. methodology, best practices, and how programmers interact with the "suits."

INTERNETTECHNOLOGIESAND NETWORKING WEB DEVELOPMENT/DESIGN Try living wlthout plumblng (and eventually 1Pv6). Ugly doesn't cut it anymore, and CGI is absurd. Talk about networking topics including protocols, design, Help is in sight for your site. Rnd design solutions for your administration, wireless, wired, storage, backup, certifications, projects and get ideas for building an interactive Web site. trends, and new technologies.

JAVA SECURITY We've come a long way from the old Oak tree. Lots of bad guys out there--the good guys need help. Hang out and discuss Java in whatever flavor you choose: Discuss computer and network security issues here. Just don't Iet J2SE, J2EE, J2ME, Jakarta, and so an. anyone eise know the answers!

MAC OS X TECHNOLOGY IN ACTION All about the Zen of OS X. Cool thlngs. Fun thlngs. OS X is both the present and the Mure for Mac apps. Make lfs alter hours. H's time Ia play. Whether you're into LEGQ® suggestions, oller up ideas, or boast about your new hardware. MINDSTORMS™ or turning an old PC into a DVR, this is where technology turns into tun.

OPEN SOURCE WINDOWS Source code is good; understanding (open) source is better. No defenestration here. Discuss open source technologies and related topics such as f.sk questions about all aspects of Windows programming, get PHP, MySQL, Linux, Perl, Apache, Python, and more. help an Microsoft technologies cavared in Apress books, or provide leadback an any Apress Windows book.

HOW TO PARTICIPATE: Go to the Apress Forums site at http://forurns.apress.com/. Click the New User link.