Mad about .NET A blog from Jose Fco Bonnin


23rd, October I did a session about LINQ for the .NET User Group  Madriddotnet.

Re Descubriendo A Linq
View SlideShare presentation or Upload your own. (tags: linq)

During the event we tried to know more in deep how LINQ works, from C-Omega to LINQ to SQL, doing an attempt to solve many of the questions that normally arise when you want to obtain the most of LINQ.

We found Visual Studio 2008 comes with a nice bunch of samples to helps us including visualizers like the Expression Tree Visualizer, which allows you to see the expression tree created from our queries and the LINQ Query Visualizer to see the translation done to Transact/SQL. We knew that it is possible to create queries on the fly using the Dynamic Query Library

We also talked about the benefits of the expression trees and the visitor pattern. You have some sample implementations like the one done by Matt Warren

In the last part of the event we focused on tips for LINQ to SQL to move to a multi-tier architecture. We explained how easy is to serialize LINQ entities to be used over WCF on both directions, this is from Master to Detail and from Detail to Master. How to workaround the fact that circular references are not supported by default by the DataContractSerializer. We gave some ideas about how to do local change tracking of entities when we are disconnected from the DataContext, providing some examples of complete implementations like the one done at MSDN Video (Spanish).

As you can see we talked about many different things and we verified how LINQ can help us during our day to day work making our life much easier if we apply some good practices.

If you attended to the event I hope you enjoyed as much as I did.

On Tuesday I did an online webcast about the CLR. I hope the people who joined us enjoyed the event and found the contents interesting.

The event was recorded and you can download it from the Microsoft Events website (Spanish).

During the presentation I did a demo in which I was showing how we can see with WinDBG when a method has been jitted or not. We saw it for the constructor but I stopped before show it for other methods to avoid wasting too much time on the same thing.

One of the attendees has asked me today why the method was shown as not jitted even after it was clearly executed. The problem was simply that I attached WinDGB to the release version of my demo application and the JIT optimized the method replacing it by an inlined version. If I had attached the debug version this would not happen and the method would be shown as jitted. If you want to have more information about it I widely explained in a previous post about Inline methods where I used the same demo application as in the webcast.

Around a week ago Culminis announced the next phase of the Culminis transformation has started.

As you probably know Culminis has become a volunteer organization similar to Ineta. This change started long time ago, something that Graham Watson explained with a post describing the key changes about how Microsoft would support the User Groups from now.

I must confess my first reaction was not very positive, I loved how Culminis was working until that day and I was afraid how the new volunteer structure would affect all the services provided.

In any case, I'm sure all the people we are volunteering at Culminis will do our best to satisfy the demands of the user groups. So, now it's time to give our maximum support to the board of directors. If you want to know more about them you can check it here.

"Types may declare locations that are associated with the type rather than any particular value of the type. Such locations are static fields of the type. As such, static fields declare a location that is shared by all values of the type. Just like non-static (instance) fields, a static field is typed and that type never changes. Static fields are always restricted to a single application domain basis, but they may also be allocated on a per-thread basis."

The paragraph above is the definition of static field extracted from the CLI specification. The text means that when we create a static field "f" inside a class "C", the value will not belong to any of the instances we create of C, instead its value is shared across all the instances and therefore "belongs" to the type C itself.

I've created a very simple class with one static and two instance fields, which you can see below.

   1: public class BusinessLogic
   2: {
   3:     public int instanceField1;
   4:     public int instanceField2;
   5:  
   6:     public static int staticField3 = 3;
   7:  
   8:     public BusinessLogic()
   9:     {
  10:         instanceField1 = 1;
  11:         instanceField2 = 2;
  12:     }
  13: }

I've run the code and I've created 5 instances of the class above, which we will check with WinDBG. To do it we can execute the next command:

!DumpHeap -type BusinessLogic

That will show something similar to the next:

Address               MT     Size
01dfa98c      006668c4      16    
01dfe898     006668c4       16    
01e027a4     006668c4       16    
01e0668c     006668c4       16    
01e13104     006668c4       16    
total 5 objects
Statistics:
      MT    Count    TotalSize   Class Name
006668c4        5           80        BusinessLogic
Total 5 objects

Once we have the address of the 5 instances we created we can dump the objects one by one by using the command !DumpObj [Address]. If we take the first one it will display something similar to:

Name: BusinessLogic
MethodTable: 001c68bc
EEClass: 00281abc
Size: 16(0x10) bytes
Fields:
          MT      Field   Offset   Type                VT   Attr         Value    Name
6f642b38  4000001        4      System.Int32     1    instance  1           instanceField1
6f642b38  4000002        8      System.Int32     1    instance  2           instanceField2
6f642b38  4000003       1c     System.Int32     1    static       3           staticField3

What we have done with this command is to examine the fields of one of the instances in memory of BusinessLogic. We can see that the object has the fields instanceField1, instanceField2 and staticField3 and its values are 1,2 and 3 respectively. So, all is as expected.

Lets focus now on the cool thing of static fields. We can see how "staticField3" is shared across al the instances we create of BusinessLogic by examing the EEClass of the objects. The 5 instances we created before have the same EEClass: "00281abc". If we examine it with the command !DumpClass 00281abc we will see that "staticField3" is present at EEClass level and its value is already initialized.

Class Name: BusinessLogic
mdToken: 02000002
Parent Class: 6f3d3ef0
Module: 001c64f0
Method Table: 001c68bc
Vtable Slots: 4
Total Method Slots: 6
Class Attributes: 100001 
NumInstanceFields: 2
NumStaticFields: 1
      MT          Field  Offset   Type                 VT    Attr         Value   Name
6f642b38    4000001        4      System.Int32   1     instance              instanceField1
6f642b38    4000002        8      System.Int32   1     instance              instanceField2
6f642b38  4000003      1c    System.Int32   1     static           3     staticField3

At this point we have demonstrated how the static fields and their values are shared across all the instances we create of a class.

In this sample we have used value types for the static field, but this also applies for reference types. This is very cool, because it allow us creating class designs where objects with a heavy load construction can be instantiated just once  i.e.

static object staticField;
....
if (staticField == null)
       staticField = new object();

This simple code will allow sharing the same instance of staticField across the entire application domain helping with the performance if staticField is hard to construct.

This does not mean that from now you must create all your "hard to construct" fields as static, because like always the gold hammer does not exist and static fields have a downside.

As we have seen the static field values are related to the EEClass, which are allocated on the loader heaps that are AppDomain specific, so this means they will be in memory until the AppDomain is unloaded.

Some time ago I read the .NET 3.5 Service Pack 1 would bring some nice improvements in the JIT compiler for the x86. Among them there were some modifications regarding how the JIT inlines methods (see my previous post about inlining).

Today I've seen this post from Vance Morrison where describes the heuristic used to determine when a candidate method must be inlined or not. Which according to him looks like follows:

"1. Estimate the size of the call site if the method were not inlined.

2. Estimate the size of the call site if it were inlined (this is an estimate based on the IL, we employ a simple state machine (Markov Model), created using lots of real data to form this estimator logic)

3. Compute a multiplier. By default it is 1

4. Increase the multiplier if the code is in a loop (the current heuristic bumps it to 5 in a loop)

5. Increase the multiplier if it looks like struct optimizations will kick in.

6. If InlineSize <= NonInlineSize * Multiplier do the inlining."

I invite you to read the entire post, I've found it very interesting.