Thursday, 18 July 2013

.Net c# parallel yield

yield is a very useful keyword in C# that allows you to create dynamic enumerators of stuffs without having to fill in a List<T> of things you want to return first. The generated code builds a state machine that will go forward, step by step, whenever the caller calls MoveNext on the IEnumerable it gets back (usually using foreach).


static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Console.WriteLine(String.Join("\n", Process(input)));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    foreach (var item in input)
    {
        yield return "Process " + item;
    }
}
 
// Output :
// Process A
// Process B
// Process C
 
The second really useful thing is Parallel.ForEach. Whenever you have to process loads of independent data that are CPU hungry you can launch the process in parallel and have it scheduled for you by the .NET runtime.

static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    Process(input);
    w.Stop();
 
    Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
}
 
static void Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    Parallel.ForEach(input, item =>
        {
            // Something long
            Thread.Sleep(1000);
        });
}
 
// Output :
// ~ 1s although we had 3 stuffs that each took 1s
 
What if we could write that?

 
static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    var result = Process(input);
    w.Stop();
 
    Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
    Console.WriteLine(String.Join("\n", result));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    Parallel.ForEach(input, item =>
        {
            // Something long
            Thread.Sleep(1000);
             
            // >>>> THE POWER !!
            yield return "Process " + item;
        });
}
 
But no we can’t because “The yield statement cannot be used inside an anonymous method or lambda expression“.
You obviously can’t mix those two pieces of magic together. In fact, if we could this would produce some of the weirdest bugs ever if something went wrong. But maybe we can’t build something that looks like it, for the sake of doing it?

static void Main(string[] args)
{
    var input = new[] { "A", "B", "C" };
 
    Stopwatch w = new Stopwatch();
    w.Start();
    var result = Process(input);
 
    Trace.WriteLine(String.Format("{0}s before enumerating", w.Elapsed.TotalSeconds));
    Trace.WriteLine(String.Format(String.Join("\n", result)));
    Trace.WriteLine(String.Format("{0}s after enumerating", w.Elapsed.TotalSeconds));
}
 
static IEnumerable<string> Process(IEnumerable<string> input)
{
    if (input == null)
        throw new ArgumentNullException("input");
 
    var workQueue = new ConcurrentQueue<string>();
    Exception workException = null;
    var completed = false;
 
    // This task will run on its side in another thread
    Task.Run(() =>
    {
        try
        {
            Parallel.ForEach(input, item =>
                {
                    // Something long
                    Thread.Sleep(1000);
 
                    // Push our results here
                    workQueue.Enqueue("Process " + item);
                });
        }
        catch (Exception ex)
        {
            // We don't want a crash to be lost in another thread
            // so we have to bring it back somehow on the main thread
            workException = ex;
        }
 
        completed = true;
    });
 
    // Not the most elegant, but it's just for fun so ...
    while (!completed)
    {
        string item;
        if (workQueue.TryDequeue(out item))
            yield return item;
        else
            Thread.Sleep(1); // remember, just for fun
    }
 
    // We don't want to lose the last items
    string finalItem;
    while (workQueue.TryDequeue(out finalItem))
        yield return finalItem;
 
    // Buble the exception if there's one
    if (workException != null)
    {
        throw new Exception("Error while doing stuffs", workException);
    }
}
Output:
0.00039s before enumerating
Process B
Process A
Process C
1.0398348s after enumerating
Notice than we did have an “yield behavior” as the processing was not executed on the call to Process, and how the whole process took 1s where it has 3 items that each took 1s. We also don’t have a reliable order anymore, it could have been any combination of B, A and C.

Monday, 10 June 2013

SQL Server 2014 New Features

Although it doesn’t seem possible so soon, Microsoft announced SQL Server 2014 at this year’s TechEd 2013 conference in New Orleans. Quentin Clark, Microsoft Corporate Vice President for SQL Server, said that Microsoft is getting ready for the upcoming SQL Server 2014 release. Some of the most important new features in SQL Server 2014 include the following:

In-Memory OLTP Engine
The new In-Memory OLTP Engine (formerly code-named Hekaton) will provide OLTP performance improvements by moving selected tables into memory. The In-memory OTLP Engine works with commodity hardware and won’t require any application code changes. A built-in wizard will help you to choose which tables go in memory and select the stored procedures that will be compiled into machine code for high performance execution.
EdgeNet, an early adopter, saw a 7X performance increase with no code changes. Microsoft claims that some applications can achieve a 50x performance boost using the new In-Memory OTLP engine.

Backup Encryption
Encrypting backups gets simpler in SQL Server 2014.  Check out a great illustration of the how you can prevent anyone from taking your backup file and restoring it to another database server with the new SQL Server 2014 encryption capabilities by reading My Favorite New Feature in SQL Server 2014 by Joey D'Antoni.

Business Intelligence
SQL Server 2014 includes business intelligence (BI) improvements to help build and support vast databases and data warehouses. Learn more about what SQL Server 2014 will do for your business Intelligence efforts in Upcoming Business Intelligence Enhancements in SQL Server 2014 by Kevin Kline.

In-Memory OLTP Engine
In-Memory OLTP significantly improves the OLTP workload and reduces the time required for processing. The performance gains depend on the hardware infrastructure you have and how you are writing your queries. Get more details from Arshad Ali in SQL Server 2014 In-Memory OLTP Architecture and Data Storage.

Memory Optimization Advisor
The SQL Server 2014 Memory Optimization Advisor will help you quickly analyze your tables and walks you through reviewing and migrating disk-based table to In-Memory OLTP tables. Greg Larsen give you a walk-through of how to use the Memory Optimization Advisor tool to migrate a table in the AdventureWorks2012 database. See, SQL Server 2014 Memory Optimization Advisor.

Windows Azure Integration
SQL Server 2014 includes the ability to use Windows Azure for offsite backup storage and as a disaster recovery site. With SQL Server 2014 you can backup and restore your databases from copies stored in Windows Azure, which can quickly and easily provide off-site storage for all backups. More specifics are available in SQL Server 2014 CTP2 and Azure Backups by Joseph Karnes.