Monday, May 20, 2013

Generics and Boxing Capabilities

Generic classes and Boxing techniques are fairly common practice.  It is often under appreciated.  If we look at a linked list we see that it is using both simultaneously.  It is a great implementation, even though performance can both be improved and hurt by it.  This is a crucial part of understanding how these topics coincide.  The LinkedList<T> from the .NET framework is just one example of this type of concept, and probably in a weaker example.

LinkedList(T) MSDN DOCs

If you want to understand this class further viewing forum topics regarding LinkedList pros and cons would be wise.

This post however is about taking this concept to a new level.  In many application development practices we work with Hierarchies.  They're often coded to be specific to the application.  Sometimes, we implement base classes for this architecture because we use it so often, but how much further can we take such a technology?  Can it be improved upon?  Obviously this is rhetorical, and theoretical.  Not only can we make the assumption there are no code practices that cannot be improved upon, we can also use this case as an example of such.

The run down of how we using Boxing and Generics to take this tech further is actually not that complex.  Linked lists get their benefit from faster insertion and navigating related objects.  Same sort of reason we use Hierarchies often.  One weakness of hierarchies is always starting at the top.  This implementation is two part.  The data is actually stored for the tree in more ways than one.  And it is retrieved in more ways than one as well. 

Storage
We store the hierarchy in two crucial ways.  Since this is a full generic class we have to create boxing for the nodes.  The nodes store information about the level parent and child relations.  So, we can still start from the top of a tree and iterate down the nodes like normal.  There's a new trick though for faster access.  Sometimes, we need to access only data a few levels deep.  Or all items on a particular level only.  This is why the storage is actually storing nodes in arrays for each level as well.  There is no distinction in this storage regarding parents and children, just all nodes on that level.  There is one trick to this that was discovered by accident, but absolutely incredible.  Children can actually be added first.  The other one that was intentional is that an array of values can be converted into a hierarchy.  My test project acftually converts an array of random integers into a hierarchy driven by digits where multiples of ten define the level.  Looks like this:

1000
   1100
      1110
         1111

The way this system is designed such generation is purely algorithmic or interface driven.  Very cool and very powerful.  May sound kinda lame but if you're into "fancy" code... this is right up your alley.

Retrieval
Since we've stored the data in this way, we can do some incredible things.  One example, say we have a tree 5 levels deep, but the upper 4 levels just contain informational data not important to our actual processing.  In most oldschool hierarchies this would still have to iterate all levels to get the bottom.  Not here.  We can pull just level 5 and not even acknowledge the parents even exist.  Pretty cool huh?  (Pretty simple too....)  This structuring also gives a few benefits in speed.  When retrieving nodes where the parent matching a condition(yes seriously) this is very easy and faster than it would normally be.  If we already have a node we just access it's children which prevents us from having to navigate and compare the entire level.  This is normally how we would do it, just felt it important to note this implementation does not exclude that. 

The ways in which the data is accessed is always the fasted option to retrieve the value desired given the information supplied.  In many cases faster than it would normally be from a normal hierarchy setup, but admittedly not all.  It's functional and optimized in many ways, but as many practices teach us, functionality often sacrifices performance.

Code Snippet
Below is a quick snippet from the integer example mentioned:  (There are other parts not visible here excluded to avoid confusion)



No, I am not kidding... It's that simple... And yes... this works flawlessly after 100s of tests.

Fun stuff right?  =P

Saturday, May 4, 2013

Extension Method Insanity!!!

Extension methods are something I've known about for a while, but I have realized some new things in their practice recently that make them only that much more fascinating.  The first thing is to understand exactly what they are.  An extension method is "actually" a static method where the first argument designates it being available as an instance method.  Here is a snippet of one for syntax.

The above snippet is a simple extension that can be called on ANY IEnumerable<T> to wrap it within a TSList object(this is just a thread safe list I created).  Pretty cool, but doesn't do much.  This is way I would use them mainly when I first discovered them.  It works well to reduce code lines a good bit.

RECENT DISCOVERY #1

So, given that extension methods are trully static methods, we can actually call them on any field/property that matchs the first argument type.  The value CAN be null!!!  This works well in a few other cases.  Here's another snippet of a simple use case.


So, the above extensions allow any  event handler to be called using one line instead of the normal two to ensure it's not null.  Yawn.... these two examples are really not that exciting.

RECENT DISCOVERY #2

Extensions can actually be used to do incredible things with reinstantiating objects, and thread safety during that change.  In the snippet below I am taking an array, we don't need to know what kind, and resizing it while maintaining thread safety.  There are other extension methods for pulling the values etc. while utilizing the same thread safety techniques.



The using brackets are due to a Smartlock class I use which is instantiated by the CreateLock EXTENSION method on objects with the ICollection interface.  If you review this closely you should see that it pulses both the previous lock and the new lock when a new array is created.  It does this to ensure that the other thread safe extensions will be pulsed if needed one way or another.  (This has been tested for stability with success).

RECENT DISCOVERY #3

Ok, this is where things get a little more interesting and becomes that much more useful with all the above practices considered as well.  Using polymorphing types extension methods can be used to change objects state and type in method chains.  I don't have quite enough space here to really showcase the whole thing, but my posting isn't a tutorial anyway, just something to think about.



When looking at this one note that it doesn't always return the same object.  It may return a "MultiSelector" or the argument passed.  There are others to force return of the parent or a child etc etc.  Methods like the first ToList example make this less fantastic, it just shows a more clear example of how extreme this can go.  If you study up on interfaces and polymorphism you can do amazing things with extension methods.  Like converting Enums to arrays.  That one is really fun =)