Apr 15 2010

A ghostly proxy

Take a look at the following pseudocode:

START to SaveSomething CALL Logger with 'Entering SaveSomething' BEGIN IF User Has Permission CALL PersistSomething EXCEPTION CALL Logger with 'Procedure Failed' END CALL Logger with 'Exiting SaveSomething' END SaveSomething

If you stand-back and squint your eyes, this will probably look a little familiar. This represents that all-to-familiar pattern where we blur the lines of responsibility because its the most convenient way to accomplish things like logging, permission checks, tracing, etc... Unfortunately, this can lead to things like the following making your code much harder to read, debug, etc...

#if (DEBUG) CALL Logger with 'Procedure Entered' #endif

The slippery slope should be obvious, but the more important issue is that we've mixed completely separate areas of concern making our code more inflexible. In this case, authorization, logging, and entity specific domain logic are all jumbled together. Putting this specific; and possibly terrible; example aside... this may be reasonable in some cases, but there are patterns that can provide us more flexibility. Ideally we'd be able to aggregate concerns such as these without being so tightly coupled. In this case, we'll explore a combination of the Proxy Pattern and the Interceptor Pattern which are commonly found in Aspect-Oriented Programming (AOP). The combination of these patterns creates what is loosely defined as a Ghost Proxy Object, although some usages do not include interception. Lets start with a simple Domain Object with a simple operation.

public class DomainObject : IDomainObject { private readonly IDal _dal; public DomainObject() : this(IoC.Resolve<IDal>()) { } internal DomainObject(IDal injectedDal) { _dal = injectedDal; } public virtual void SaveSomething(object thing) { _dal.SaveSomething(thing); } }

The class is pretty straightforward... get an object, and then save it. From a Domain perspective, that is the only concern this component needs to have. Now lets wrap this in a proxy and add methods to wire-up externally supplied delegates. The actual code to wire-up the delegates is not really important and would be pretty trivial to implement. suffice it to say, registered delegates will be called before and after the proxied method is called. The goal is to have a class that represents the base DomainObject while providing us with opportunities to execute externally registered logic. Additionally, all this should be accomplished without any changes to; or accommodations by; the base type aside from it being inheritable.

public sealed class ProxyObject : DomainObject, IInterceptable { /* The real domain object instance to be called */ readonly IDomainObject _realInstance; static IDictionary<string, BeginAction[]> _beginActions = new Dictionary<string, BeginAction[]>(); static IDictionary<string, EndAction[]> _endActions = new Dictionary<string, EndAction[]>(); public ProxyObject() : this(IoC.Resolve<IDal>()) { } internal ProxyObject(IDal injectedDal) { _realInstance = new DomainObject(injectedDal); } public override void SaveSomething(object thing) { this.InvokeBeginMethod(ref _beginActions, "Void SaveSomething(System.Object)", new[] { thing }); _realInstance.SaveSomething(thing); this.InvokeEndMethod(ref _endActions, "Void SaveSomething(System.Object)", new[] { thing }, null); } public void AddInterceptMethod(MemberInfo memberInfo, BeginAction beginAction, EndAction endAction) { /* Extension Method for instances of IInterceptable */ this.AddInterceptMethod(ref _beginActions, ref _endActions, memberInfo, beginAction, endAction); } public void RemoveInterceptMethod(MemberInfo memberInfo) { /* Extension Method for instances of IInterceptable */ this.RemoveInterceptMethod(ref _beginActions, ref _endActions, memberInfo); } }

Lets start by calling the un-proxied DomainObject to see the basic behavior in action.

IDomainObject realObject = new DomainObject(); realObject.SaveSomething("Foo");

Calling an instance of the proxy would produce the same result, but we need to inject additional functionality such as logging, tracing, security, etc... To do this, we must first create an instance of the Proxy and register the Delegates which will be called before and after proxied methods are called.

MethodInfo methodToIntercept = typeof(IDomainObject).GetMethod("SaveSomething"); ProxyObject proxyObject = new ProxyObject(); proxyObject.AddInterceptMethod(methodToIntercept, LogBeginAction, LogEndAction); proxyObject.AddInterceptMethod(methodToIntercept, PermissionCheckBeginAction, null);

Once registered, any calls to new instances of the proxy type will be wrapped with the intercepting delegate calls.

IDomainObject proxyDomainObject = new ProxyObject(); proxyDomainObject.SaveSomething("Foo");

As you can see this works fine, but this could be improved by using an IoC container. This gives us the flexibility to control this behavior externally, which provides a wide range of new options. In this case, my IoC Container returns an instance of ProxyObject which is mapped to the IDomainObject interface in an external configuration file.

IDomainObject proxyDomainObject2 = IoC.Resolve<IDomainObject>(); proxyDomainObject2.SaveSomething("Foo");

These patterns can provide some really interesting capabilities although; as you can see; they require some investment in additional code. These days, proxies such as this can be automatically created using Code Generation or Dynamic Proxy tools (here is a sample). Another important consideration is performance... Profile your application and you'll see more in memory which means more to be GC'd. In the end, this means things will be slower. Like anything else, this is all about options, so take a look and see where this pattern might fit into your tool bag. Enjoy...

Tags: , ,

Apr 12 2010

Take a byte out of time

Category: Tips and TricksJoeGeeky @ 00:01

Recently I was working on a custom transport and at some point I realized my payload had grown to an unacceptable size. After some analysis I discovered that DateTime structures represented the bulk of the problem. On reflection this was completely obvious since the default binary representation of a DateTime is a long (e.g. 8 bytes). This allows us to store date representations across just over 10,000 years.

Normal 8-Byte DateTime: ~10005 Years

In my case; and probably many of yours; I don't need to work with such a wide range of dates. This means I can shrink my dates by half and still have a sufficient range of dates to meet the needs of most applications. 

4-Byte DateTime: ~136 Years

To do this, we can take a lesson from the POSIX community which has been converting Unix Time to and from other formats for a long time. This is a simple pattern that allows us to reuse the built-in DateTime structures. What we need are methods to convert to and from our offset 4 byte representation.   

public static class TimeOffsetExtensions
{
    static readonly DateTime _timeReference = new DateTime(2010, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
 
    public static DateTime ToDateTime(this int timestamp)
    {
        return _timeReference.AddSeconds(timestamp);
    }
 
    public static uint ToOffsetTimestamp(this DateTime instance)
    {
        TimeSpan diff = instance - _timeReference;
        return (uint)Math.Floor(diff.TotalSeconds);
    }
}

One of the keys to this is setting a common time offset. Above you will see that I set my offset to start at 01/01/2010. As long as this never changes, then you can adjust this as needed to meet your particular requirements. With these methods in place we can apply them in reading/writing to transports, stores, or whatever. Here is an example of writing a DateTime in its short form:

DateTime time = DateTime.UtcNow;
 
byte[] offsetDateBytes;
 
using (var stream = new MemoryStream())
{
    using (var writer = new BinaryWriter(stream))
    {
        writer.Write(time.ToOffsetTimestamp());
    }
 
    offsetDateBytes = stream.ToArray();
}

Here is an example of reading the offset bytes back into a normal DateTime object:

DateTime recoveredDateTime;
 
using (var stream = new MemoryStream(offsetDateBytes))
{
    using (var reader = new BinaryReader(stream))
    {
        recoveredDateTime = reader.ReadInt32().ToDateTime();
    }
}

That's all there is to it... Apply this in good health. 

Tags: ,

Apr 10 2010

Wrap config settings for speedier access

Category: Tips and TricksJoeGeeky @ 08:11

Some time ago I wrote about creating custom configuration sections as an alternative to using appSettings. At the time, the focus revolved largely around the need for hierarchal and strongly typed configuration points, neither of which are really a feature of sections like appSettings. Although I feel like I'm picking on the poor little appSettings a little bit, if they're used incorrectly they can really hurt products that demand really high performance. Lets look at a common pattern applied to using appSettings:

string aString = ConfigurationManager.AppSettings["AString"];

The thing to remember is, these calls are bound to interactions with the applications configuration file and the ConfigurationManager does very little to mitigate the expense for this type of call. As an I/O bound resource, repeated calls can be very costly. Whether you're using appSettings or another config section, the only way to mitigate I/O bound costs is to cache your settings. There are lots of patterns to do this, here is a quick example of just one.

Lets start with an interface representing our configuration settings. Strictly speaking an interface is not required, but makes it easier to inject configurations using the Dependency Injection pattern later on.

public interface IConfig
{
    string AString { get; }
    bool BBoolean { get; }
    int CInt { get; }
    DateTime DDate { get; }
}

Now lets implement the interface. In doing so we need to accomplish the following:

  • Load configuration points from file
  • Cache the configuration results
  • Provide a mechanism to refresh the cached configuration

public class Config : IConfig
{
    private static IConfig _config;

    public Config()
    {
        AString = ConfigurationManager.AppSettings["AString"];
        BBoolean = Convert.ToBoolean(ConfigurationManager.AppSettings["BBoolean"]);
        CInt = Convert.ToInt32(ConfigurationManager.AppSettings["CInt"]);
        DDate = Convert.ToDateTime(ConfigurationManager.AppSettings["DDate"]);
    }

    #region IConfig Members

    public string AString { get; private set; }
    public bool BBoolean { get; private set; }
    public int CInt { get; private set; }
    public DateTime DDate { get; private set; }

    #endregion

    public static IConfig Current
    {
        get
        {
            if (_config == null)
                _config = new Config();

            return _config;
        }
    }

    public static void Refresh()
    {
        _config = new Config();
    }
}

As you can see this is essentially a singleton pattern. While this may seem a little boring, its clean, testable, and can be extended to provide a wide range of related functionality. The real test is whether or not this is actually any faster... Creating a simple loop test we can get a sense of how this stacks up.  

private static void Main(string[] args)
{
    const int MaxReads = int.MaxValue / 2;
    var watch = new Stopwatch();
 
    Console.WriteLine();
 
    watch.Start();
    for (int i = 0; i < MaxReads; i++)
    {
        IConfig config = Config.Current;
 
        string AString = config.AString;
        bool BBoolean = config.BBoolean;
        int CInt = config.CInt;
        DateTime DDate = config.DDate;
    }
    watch.Stop();
 
    Console.WriteLine("Using Cached Config - Rate/Sec: \t{0}", MaxReads / watch.Elapsed.TotalSeconds);
 
    watch.Reset();
    watch.Start();
    for (int i = 0; i < MaxReads; i++)
    {
        string AString = ConfigurationManager.AppSettings["AString"];
        bool BBoolean = Convert.ToBoolean(ConfigurationManager.AppSettings["BBoolean"]);
        int CInt = Convert.ToInt32(ConfigurationManager.AppSettings["CInt"]);
        DateTime DDate = Convert.ToDateTime(ConfigurationManager.AppSettings["DDate"]);
    }
    watch.Stop();
 
    Console.WriteLine("Using ConfigurationManager - Rate/Sec: \t{0}", MaxReads / watch.Elapsed.TotalSeconds);
    Console.ReadLine();
}

Here are the results...

As you can see, the difference in performance can be dramatic. Although I used appSettings as the center of this example, the same basic problem exists for any configuration section (Ex. connection strings, custom sections, etc...). Hope this helps.

Tags: ,

Mar 19 2010

Putting your DataTable on a diet

Category: Tips and TricksJoeGeeky @ 01:08

As the name suggests, the System.Data.DataTable is a fat object type. It's true that there's a lot you can do with this class, but this may come at a pretty high price. To demonstrate this, lets start by creating two in-memory structures and compare their sizes using WinDbg. The size of each structure will be a conservative 500,000 records, each with a puny 7 columns of 32 Bit Integers. If you've developed high-performance applications you know this is a pretty conservative amount of data, but this should still make the point.

const int MaxItemCount = 500000;

Our first structure is built around the suppossed fat DataTable. 

var table = new DataTable("MyFatTable");
table.Columns.AddRange(new[] {new DataColumn("A", typeof(int)),
                                new DataColumn("B", typeof(int)),
                                new DataColumn("C", typeof(int)),
                                new DataColumn("D", typeof(int)),
                                new DataColumn("E", typeof(int)),
                                new DataColumn("F", typeof(int)),
                                new DataColumn("G", typeof(int))});
for (int i = 0; i < MaxItemCount; i++)
{
    DataRow row = table.NewRow();
    row["A"] = i;
    row["B"] = i;
    row["C"] = i;
    row["D"] = i;
    row["E"] = i;
    row["F"] = i;
    row["G"] = i;
    table.Rows.Add(row);
}

Next we'll create a more traditional object collection so we can see what the DataTable "might" be costing us.

public class DataItem
{
    public int A { get; set; }
    public int B { get; set; }
    public int C { get; set; }
    public int D { get; set; }
    public int E { get; set; }
    public int F { get; set; }
    public int G { get; set; }
}

IList<DataItem> data = new List<DataItem>();
for (int i = 0; i < MaxItemCount; i++)
{
    var dataItem = new DataItem();
    dataItem.A = i;
    dataItem.B = i;
    dataItem.C = i;
    dataItem.D = i;
    dataItem.E = i;
    dataItem.F = i;
    dataItem.G = i;
    data.Add(dataItem);
}

If we run the sample and create a Dump file, we can see how much memory is being consumed by each type of structure. The DataRows in the DataTable make up almost twice the amount of memory as that of the more traditional object collection (e.g. DataItems). Keep in mind this was a really simplistic sample, and real-world structures will likely be much larger (in row count and columns). Aside from memory pressure, the DataTable will cause your application to spend more time in Garbage Collection, which will translate to your application being slower.

Spend a little time profiling your application and you'll likely find other large concrete implementations with hidden costs. In this case, the solution is easier than you might think. In many cases, all we really need from a DataTable is the underlying DataReader. Assuming that is true in your case, all you really need to do is implement a custom System.Data.IDataReader. This is a fairly large interface but it is really easy to work with and many solutions don't actually need every method implemented. This allows you to start simple and add additional features when and if you need them.

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

public sealed class GenericListDataReader<T> : IDataReader
{
    private readonly IEnumerator<T> _enumerator;
    private readonly List<PropertyInfo> _properties = new List<PropertyInfo>();

    public GenericListDataReader(IEnumerable<T> list)
    {
        _enumerator = list.GetEnumerator();

        const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty;

        /* Map properties to columns based on the order in which they occur */
        foreach (PropertyInfo property in typeof(T).GetProperties(flags))
        {
            /* Only support adds properties that can be mapped to database types */
            if (property.PropertyType.IsPrimitive ||
                property.PropertyType == typeof(string) ||
                property.PropertyType == typeof(DateTime))
            {
                _properties.Add(property);
            }
        }
    }

    public bool Read()
    {
        return _enumerator.MoveNext();
    }

    public int FieldCount
    {
        get { return _properties.Count; }
    }

    public string GetName(int i)
    {
        return _properties[i].Name;
    }

    public Type GetFieldType(int i)
    {
        return _properties[i].PropertyType;
    }

    public object GetValue(int i)
    {
        return _properties[i].GetValue(_enumerator.Current, null);
    }

    public void Close()
    {
        _enumerator.Dispose();
    }

    public void Dispose()
    {
        Close();
    }

    #region IDataRecord Members
        /* throw NotSupportedException for all remaining members */
    #endregion

    #region IDataReader Members
        /* throw NotSupportedException for all remaining members */
    #endregion

}

Get the full class GenericListDataReader.cs (4.30 kb).

This is a really basic wrapper around enumerable types. As a side benefit your Data Reader is inherently Mockable which makes testing easy as well. As an IDataReader, this structure can be used to bridge the gap between traditional object structures and data persistence layers. Here is a simple example using the SqlBulkCopy structure to persist our previous collection into a database.  

using (var dataReader = new GenericListDataReader<DataItem>(data))
{
    using (var bulkCopy = new SqlBulkCopy("A Connection String"))
    {
        bulkCopy.DestinationTableName = "Target Table Name";

        bulkCopy.ColumnMappings.Add(0, "ColumnA");
        bulkCopy.ColumnMappings.Add(1, "ColumnB");

        bulkCopy.WriteToServer(dataReader);
    }
}

So whats the lesson here? It has two parts... As I said in the beginning, the DataTable is fat. Also, if you're writing high performance applications, look closely at those "free" concrete implementations, they may be costing you more than you think.

Tags: ,

Mar 12 2010

A faster way to take out the Garbage

Category: Tips and TricksJoeGeeky @ 02:15

If you've been working with Intermediate Languages for any amount of time you're probably aware of how expensive Garbage Collection can be. This invariably leads to discussions related to how to properly Dispose objects; which is very important; or how to "force" collection which is generally a really bad idea. I do not intend to revisit these overly blogged topics, and will assume you already understand the benefits and/or consequences of both. With that said, there is one aspect of this discussion which is not widely understood within the .NET community. Unfortunetaly, this can represent a missed opportunity for many applications suffering from collection performance issues.

Listen closely to your collegues when discussing this subject and you will likely hear them speaking of the "the" Garbage Collector (GC), and herein lies the problem. There isn't one GC, there are actually three different GC configurations, each having unique characteristics and potentially some drawbacks for certain types of applications. Lets take a look at each one and then we can see how to override the default selection made by the .NET Framework.

Workstation (Non-Concurrent)

This GC has one heap per process and performs all collection on the applications main thread. Having multiple processors and/or cores does not change this configuration. Although not the default for any application type, it can have subtle advantages for non-graphical applications such as Consoles.

Workstation (Concurrent)

This GC has one heap per process and it has one dedicated GC thread per process. Having multiple processors and/or cores does not change this configuration. This GC is the default for Console and WinForm applications. The dedicated GC thread allows the application to remain more responsive while performing collection. For WinForm applications, this can be more pronounced as a result of windowing refresh/invalidation. 

Server

This GC has one GC heap per Processor and one dedicated GC thread per GC heap. As indicated by its name this GC is optimized for server-based applications. This provides better scalability by allowing a process to create objects in multiple heaps. This allows for better load-balancing and consequently is the default for all ASP.NET applications, including web services.

As it turns out, the Server characteristics can be really beneficial for other Server-style applications like Windows Services. Enabling this GC can be quite handy but the question is, how to know when this may be better for your application. Unfortunetally, the answer to this can be quite varied but there is one simple performance counter that may be a good signal to enable this capability. Take a look at the following Performance Counter:

This counter tells you how much time; as a percentage; your application is spending in GC (duh). If your application is averaging percentages above 20%-30% then enabling the Server GC may be beneficial for you. Enabling this or other GC modes can be done in the config file as follows:

<configuration>
  <runtime>
    <gcServer enabled="true"/>
  </runtime>
</configuration>

As with anything, you need to test, test, test to ensure this provides a benefit to you. Enjoy...

Tags:

Mar 5 2010

When "Activator" is just to slow

Category: Tips and TricksJoeGeeky @ 05:00

Here's another quick tip; again... pun intended. If you are writing high performance dynamic code you have likely found yourself using the "Activator" to instantiate instances of objects. This is commonly the case when employing Inversion of Control (IoC) patterns, or using reflection to discover and create types at runtime. Here are a couple typical examples:

IFoo foo = (IFoo)Activator.CreateInstance(typeof(Foo));

IFoo foo = Activator.CreateInstance<Foo>();

These approaches can be perfectly reasonable until you are constructing the same types often (as with IoC) or you have more substantial performance requirements. So what's wrong with using the "Activator"? In a couple words... It's slow! Don't take my word for it. Build your own test rig and it should become obvious.

Still not sure? What you need is another point of reference, such as a more performant alternative. Here comes Lambda Expressions to the rescue. Lets see how we can leverage this capability to rival the Activator.

private static Func<T> GetConstructor<T>() where T : class, new()
{
    ConstructorInfo constructorInfo = typeof(T).GetConstructor(new Type[0]);
    return Expression.Lambda<Func<T>>(Expression.New(constructorInfo))
                .Compile();
}

The above routine will create a compiled constructor for a given Type. Although you have to keep track of this state, it can easily be managed within a Type construction Factory such as those built into IoC Containers. With this method you can create as many instances as you need and then release the associated resources.

var constructor = GetConstructor<Foo>();
IFoo foo = constructor();

If we apply the same test rig used previously and retest with this approach, it is easy to see how things stack up.

Although not covered here, this sample can easily be extended to support parameterized constructors. Enjoy, and use in good health.

Tags:

Feb 19 2010

What the heck is a torn-read?

If you've written any high performance asynchronous applications you may have found yourself putting up Memory Barriers to avoid those costly thread locks. More commonly known as Memory Fences, this technique can allow you to create lock-free read-modify-write operations which can give you that little extra bit of performance that some applications need. To be fair this is an advanced technique so if you are embarking on this sort of thing be very careful and do lots of testing.

The problem with using lock-free approaches is that you now have to deal with Atomicity on your own and this may not always be as straightforward as you might think. Lets look at a couple simple examples of what is and is not Atomic.

Single reads and writes are always atomic:

Int32 number = 123; /* single writes are atomic */
number.ToString(); /*single reads are atomic */

Unary operations are another story since they consist of two operations (one read and one write). As a result, using them in a lock-free environment can lead to unexpected results:

number++;
number += 2;

This means that another thread or process could alter the value of 'number' in between its read and write. When this happens you will certainly be left scratching your head wondering how 1+= 1 could possibly equal 1294.

64 Bit types present an even more subtle problem. Single reads or writes of 64 Bit types 'may' not be atomic the same way their 32 Bit counterparts are. Thats right, I said 'may' not... Here's the issue. To store a 64 Bit value in a 32 Bit environment the runtime needs two separate memory locations and consequently there are two separate instructions to read or write a value. This creates a vulnerability similar to unary operations called a torn-read. When this occurs one of the memory locations reflects a value from one thread or process while the other reflects a value from another thread or process. In the end, this will cause you no end of pain and is next to impossible to debug.

Thread or Process A writes 5,000,000,000 which is stored in two 32 bit registers as follows:

10101010000001011111001000000000 -- 10101010000001011111001000000000

Thread or Process B writes 10,000,000,000 which is stored in the same two 32 bit registers as follows:

11010100000010111110010000000000 -- 11010100000010111110010000000000

A read by either could result in the following combination:

10101010000001011111001000000000 -- 11010100000010111110010000000000

In 64 Bit environments this is not an issue because they only need one memory location and can read and write with only one instruction.

So how can you use a lock-free pattern and avoid this problem on 32-bit platforms? There are a couple ways to deal with this, but really only one worth mentioning... Interlocked.

Interlocked.Increment(ref number);

This class provides a number of methods to help ensure interaction with types such as these are done atomically.

So what is the moral of this story?  If you are going lock-free... Test, test, test...

Tags: ,

Feb 11 2010

Hiding from the debugger

Category: Tips and TricksJoeGeeky @ 18:56

There is no doubt the modern debugger has made developers lives so much easier and without it... well... lets just not think about that. More specifically, the Microsoft Visual Studio debugger is really a beautiful piece of engineering kit. Having praised it, now lets talk about the pain it can cause us. Tools like this have become so advanced, providing so much detail that sometimes it can actually hamper our efficiency or in some cases give away more information than we are comfortable with. Consider the following examples:

  • When you have deep inheritance chains, auto-generated code for things like designers, or methods with high Cyclomatic Complexity, stepping through code can take considerably longer than you might like and if segments of the code are already trustworthy, you may wish to have the Debugger ignore them when stepping through code
  • When dealing with classes that have large numbers of private variables & properties that reflect the same values this can clutter up the variables windows makings your debugging experience less then optimal
  • When developing applications to be consumed by third-parties, you may wish to hide select members from the debugger. This could be a desired part of your obfuscation process or simply to make the debugging experience less confusing for consumers of your API

Lucky for us, these and other scenarios can be dealt with easily by using facilities provided within the System.Diagnostics namespace.

Lets start with hiding code from the Debugger:

[DebuggerHidden]
public void MyHiddenMethod()
{ /* Do something */ }

By simply appling the attribute DebuggerHidden when stepping through code, any time this method is encountered by the debugger, it will skip over it. This will occur even if the method or a descendant has a breakpoint set.

Hiding select members can be just as easy. Lets say we have a simple variable that we want to hide. Before hiding the variable we can see that it is clearly visible in the debugger.

private string _internalMember;

To hide this member, all we need to do is apply the DebuggerBrowsable attribute:

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string _internalMember;

When debugging you will see that the member is now missing from variable windows such as Locals.

While writing this, I tried to think of some basic rules for when to apply this. The truth is, there aren't any "rules". This is something you will have to apply when it feels right for your situation. Keep in mind that applying techniques like this can lead to hiding important information, on the other hand it can make debugging experiences more productive. With that said, remember to never apply these techniques until you are absolutely sure the code being hidden is trusted. Take a look at the System.Diagnostics namespace for more tricks you can use to make you debugging experience better.

Tags: ,

Feb 5 2010

Find it faster amongst the collection

Category: Tips and TricksJoeGeeky @ 04:00

Here's a quick tip; pun intended. We have all had to find something in a Collection or List and in many cases it probably looked something like the following:

var tokens = new List<string>();
...
if (tokens.Contains("Foo")) { /* Do something */ }
 

Pretty simple, but if you are looking for multiple values you might have something like this:

if (tokens.Contains("Foo")) { /* Do something */ }
else if (tokens.Contains("Bar")) { /* Do something else */ }

or even this...

foreach (var searchToken in searchTokens)
{
    if (tokens.Contains(searchToken)) { /* Do something */ }
}

All these work fine, but under a large load or with very large collections you may find that these patterns are incredibly slow. There is however another approach that is substantially faster and most people I've spoke to never even knew it was an option. The alternative...

IEnumerable<string> values = tokens.Intersect(new[] { "Foo", "Bar" });

This is a nice simple call, even if you are only looking to match a single value. Elegance aside, the important bit is the math...  Is it really faster? Your results may vary somewhat but here are some numbers; in ticks; showing the difference between Contains and Intersect in a large collection. The size of the collection is not really important, as the point lies in the relative difference between each approach... Alright... it was a collection with 21.5 million entries, and each approach searched for the same five values.

  • Using .Contains five times: 1,015,560 ticks
  • Using one .Intersect call with five search values: 71,739 ticks

Keep in mind this was done a simple desktop to your results may vary... As it turns out a .BinarySearch(x) run five times returned the same values in 230 ticks, but this approach has limitations that you will have to read about on your own. Do your own testing, and you may find this a useful alternative and might make the difference between success and failure in a production scenario.

Tags:

Jan 16 2010

Exceptional Threading

Category: Rabbit Trails | Tips and TricksJoeGeeky @ 21:27

When multi-threading applications it can be easy to lose the plot from time to time. Sometimes it can take all your energy just to remember what is running when, how to sync, lock, join, etc... Often, exception handling takes a back seat or can lose consideration with respect to where exceptions should; or will; be communicated and how they may be handled. Even if you assume you are the greatest developer who ever lived, exceptions are inevitable, and when they occur in a multi-threaded application the root cause can be very hard to isolate. In fact, depending on the type of feature being executed on a thread you may have silent failures leading to no end of rabbit-trails as dependent behaviors and/or components exhibit who knows what.

With that in mind, there are a number of patterns that can keep you out of trouble; or at least; help you isolate problems when trouble strikes. Lets tackle one of the most commonly used threading patterns first, the QueueUserWorkItem.

ThreadPool.QueueUserWorkItem(DoSomethingFeature, null);

This is something I see a lot of and unfortunately it can lead to disappointment. Any unhandled exceptions that occur in the aforementioned DoSomethingFeature() method will reach the AppDomain and will crash your application. There are; at least; two patterns we can employ to deal with this kind of problem. The first pattern focuses on catching exceptions. Thanks to lambda support, we can easily wrap our feature methods with some basic try {} catch {} blocks.

ThreadPool.QueueUserWorkItem(state =>
    {
        try
        {
            DoSomethingFeature(state);
        }
        catch (Exception ex)
        {
            //Handle the exception
        }
    });

The above approach will provide you an opportunity to catch unhandled exceptions but does not provide an elegant means of communicating to other threads so they can take action if needed. To achieve that, you could employ the Observer Pattern using static Events... Here is a simplified example:   

Define a delegate and EventArgs implementation to communicate whatever is needed to facilitate your exception handling needs...  For this sample, all we need is the Exception itself.

public delegate void CustomExceptionHandler(object sender, ExceptionArgs e);

public sealed class ExceptionArgs : EventArgs
{
    public Exception Exception { get; set; }
}

Next, define a static Event in a location that is accessible to all required areas of concern.

public static event CustomExceptionHandler OnCustomException;

With that in place, we can now queue our threads as we did before, but this time we will wire up the new event/delegate created previously to communicate exception details.

ThreadPool.QueueUserWorkItem(state =>
    {
        try
        {
            DoSomethingFeature(state);
        }
        catch (Exception ex)
        {
            if (OnCustomException != null)
                OnCustomException(null, new ExceptionArgs { Exception = ex });
        }
    });

For those layers charged with handling or responding to unhandled exceptions, they just need to subscribe to the Events. 

OnCustomException += ((sender, e) => Console.WriteLine(e.Exception.Message));

Now lets address a second commonly used unhandled exception catch pattern. You may have seen code such as follows:

AppDomain.CurrentDomain.UnhandledException += ((sender, e) => /* catch and continue */));

This approach is often misunderstood... On the surface, it may appear as a method of catching an unhandled exception and preventing your application from crashing, but testing will show that this is not true starting with .NET 2.0. This delegate is provided to allow the application to save state, log exception details, etc. but will not prevent a terminal Exception from bringing down the AppDomain. Using this for the stated purposes is still a good idea, but you will need to employ other methods such as the ones above to prevent total failure.  

Tags: , ,