Friday, March 29, 2013

c# - StreamReader vs File.ReadLines

Performance testing
Machine Configuration: Dell E6420 4 GB Ram 32- Bit i-7 Core (cores dont matter in this case.Parallel test for later)
Input File: 350+ MB tab delimited txt file

StreamReader


using System;
using System.Diagnostics;
using System.IO;

namespace FileReaderPerf

{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            try
            {
                  using (StreamReader oReader = new StreamReader(@"c:\File.txt"))
                  {
                      string sLine = oReader.ReadLine();
                      while (sLine != null)
                      {
                          Console.WriteLine(sLine);
                          sLine = oReader.ReadLine();
                      }
                  }                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;

            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",

                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds);
            Console.WriteLine("RunTime " + elapsedTime);
            Console.Read();
        }
    }
}


























StreamReader using a larger buffer size

using (StreamReader oReader = new StreamReader(@"c:\File.txt",Encoding.ASCII,false,8092))
























File.ReadLines

using System;
using System.Diagnostics;
using System.IO;

namespace FileReaderPerf
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            try
            {
                 foreach(string sLine in File.ReadLines(@"c:\File.txt"))
                            Console.WriteLine(sLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;

            string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds,
                ts.Milliseconds);
            Console.WriteLine("RunTime " + elapsedTime);
            Console.Read();
        }
    }
}


Friday, March 22, 2013

c# - Managed Parallelism,Threading using Task Parallel Library

One of my recent task was to migrate the .Net 2.0 code for processing a few thousand files.The original code used Managed Threading using ThreadPool. I wanted to update this code using .Net4.0 Task Parallel Library's Parallel.Foreach for this task.(Source: http://msdn.microsoft.com/en-us/library/ff477033.aspx)


Below is a very very trivial example.

In the code below I am getting all the folders in a given directory and processing them in parallel using Parallel.Foreach. I am using Environment.ProcessorCount(Source: http://msdn.microsoft.com/en-us/library/system.environment.processorcount.aspx ) to get the total number of core processors on my server to control the total number of cores being used for processing.In the first example I am using all the 8 cores on my server.

using System;
using System.Threading.Tasks;
using System.IO;

namespace ManagedParallelism
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                DirectoryInfo oDirectoryInfo = new DirectoryInfo(@"C:\MyFolder");
                Parallel.ForEach(oDirectoryInfo.GetDirectories(), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, (oDirectory) =>
                {
                        Console.WriteLine("TIMESTAMP: {0} INFO: PROCESSING DIRECTORY:{1}", DateTime.Now, oDirectory.Name);
                        ProcessDirectory(oDirectory);
                        Console.WriteLine("TIMESTAMP: {0} INFO: COMPLETED DIRECTORY:{1}", DateTime.Now, oDirectory.Name);
                        
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
            Console.Read();
        }
        /// <summary>
        /// Function to process each of the sub directories
        /// </summary>
        /// <param name="oDirectory"></param>
        private static void ProcessDirectory(DirectoryInfo oDirectory)
        {
            //ToDo: Add code to process each sub directory in the Raw Files Folder
            //throw new NotImplementedException();
        }
    }
}
















By changing the above code to 

Parallel.ForEach(oDirectoryInfo.GetDirectories(), new ParallelOptions { MaxDegreeOfParallelism = (Environment.ProcessorCount - 4)}

parallelism can be limited to 4 cores.This value would ideally come from a configuration file.
















Task Parallel Library does make threading easy !

Monday, March 18, 2013

An error has occurred while trying to access the log file. Logging may not function properly - Visual Studio

Recently, I started getting this error when I opened the Visual Studio IDE. After searching for the cause of this error,I found that VMWare installation was the culprit (Actually its me who forgot to uncheck Install VS plugin while installation).VMware installation adds in a plugin to Visual Studio.You can either choose to reinstall VMWare and choose not install the plugin or disable the plugin in Visual Studio IDE.

See below screenshots to disable the plugin from Visual Studio (Note:Run Visual Studio as an admin)

The error























Fix











HTH

Tuesday, March 12, 2013

c# - Multi threading using TPL

In all my previous projects I have used ThreadPool class for managed threading.I wanted to migrate the code to .net 4.5 framework and was looking at Task Parallel Library for threading.Task parallel library makes threading ridiculously easy, especially when the threads do not share resources.
Below are two implementation of parallel processing using the Parallel.Invoke function


using System;
using System.Threading.Tasks;

namespace TaskParallelLibraryExample

{
    class Program
    {
        static void Main(string[] args)
        {
            Parallel.Invoke(() => RunMillionIterations1(1), () => RunMillionIterations2(2), () => RunMillionIterations3(3), () => RunMillionIterations4(4), () => RunMillionIterations5(5));
            Console.Read();
        }

        private static void RunMillionIterations1(int i)

        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}",iIndex,i.ToString());
            }
        }

        private static void RunMillionIterations2(int i)

        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}", iIndex, i.ToString());
            }
        }
        private static void RunMillionIterations3(int i)
        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}", iIndex, i.ToString());
            }
        }
        private static void RunMillionIterations4(int i)
        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}", iIndex, i.ToString());
            }
        }
        private static void RunMillionIterations5(int i)
        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}", iIndex, i.ToString());
            }
        }
    }
}



























using System;
using System.Threading.Tasks;

namespace TaskParallelLibraryExample

{
    class Program
    {
        static void Main(string[] args)
        {
            Parallel.Invoke(() => RunMillionIterations1(1), () => RunMillionIterations1(2), () => RunMillionIterations1(3), () => RunMillionIterations1(4), () => RunMillionIterations1(5));
            Console.Read();
        }

        private static void RunMillionIterations1(int i)

        {
            for (int iIndex = 0; iIndex < 1000000; iIndex++)
            {
                Console.WriteLine("Iteration:{0} Code:{1}",iIndex,i.ToString());
            }
        }
    }
}



























Below are the screenshots of the processor utilization by the library.I have noticed a significant increase in performance due to a higher and more efficient utilization of the machine resources by the task parallel library.



Monday, March 11, 2013

wpf client for wcf service

In one of the earlier posts I had listed out the steps to create a wcf service and a client to consume the service.The client for consuming the service was a windows console client.In this post I will show the steps to create a wpf client for the consuming the same wcf service.The post is located here http://virtuoso217.blogspot.com/2012/08/windows-communication-foundation.html

Open Visual Studio and select Windows Presentation Project from the list of projects



















In the MainWindow.xaml drag and drop the following controls
TextBlock1,TextBox1 for the seed wcf service is expecting
TextBlock2,TextBox2 for the dange wcf service is expecting
TextBlock3 to display the random number received from the service
Button to invoke the wcf service















In the next step, import the service proxy generated during the creation of the service i.e. proxy.cs and the the app.config with configuration settings (See the link posted at the beginning of this post for service proxy generation)
App.config settings below


<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IRandomNumberGenerator" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:12345/ServiceExample/Service/RandomNumberGenerator"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IRandomNumberGenerator"
                contract="IRandomNumberGenerator" name="WSHttpBinding_IRandomNumberGenerator">
                <identity>
                    <userPrincipalName value="myname@office.myoffice.com" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>



In the button click event instantiate the RandomNumberGeneratorClient class of the proxy and call the GetRandomNumber method.


private void button1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                RandomNumberGeneratorClient oClient = new RandomNumberGeneratorClient();

                int iSeed = int.Parse(textBox1.Text);

                int iRange = int.Parse(textBox2.Text);

                textBox3.Text = "Random Number returned from the service: " + oClient.GetRandomNumber(iSeed, iRange);

            }
            catch 
            {
                textBox3.Text = "The service is not responding.Please make sure the service is online.";
            }
        }

Run the service and client.


 Client
Service
Client

Service

Friday, March 8, 2013

c# - Contains vs IndexOf

I found that while searching for a special character in a given string,the contains performed better when the special character was at the beginning and IndexOf performance was better when the special character was at the end of the string.

string sString = "@MyRelativelySmallStringWithSpecialCharacter";
string sString = "MyRelativelySmallStringWithSpecialCharacter@";


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ContainsIndexOf

{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string sString = "MyRelativelySmallStringWithSpecialCharacterAtTheEnd@";
                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();

                for (int i = 0; i < 1000000; i++)

                {
                    Console.Write("Iteration:" + i);
                    if (sString.IndexOf("@") != -1)
                        Console.WriteLine("Success !!!");
                }
                stopWatch.Stop();
                TimeSpan ts = stopWatch.Elapsed;

                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",

                    ts.Hours, ts.Minutes, ts.Seconds,
                    ts.Milliseconds);

                Stopwatch stopWatch1 = new Stopwatch();

                stopWatch1.Start();

                for (int i = 0; i < 1000000; i++)

                {
                    Console.Write("Iteration:" + i);

                    if (sString.Contains("@"))

                        Console.WriteLine("Success !!!");
                }

                stopWatch1.Stop();

                TimeSpan ts1 = stopWatch1.Elapsed;

                string elapsedTime1 = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",

                    ts1.Hours, ts1.Minutes, ts1.Seconds,
                    ts1.Milliseconds);

                Console.WriteLine("IndexOf RunTime " + elapsedTime);

                Console.WriteLine("Contains RunTime " + elapsedTime1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}

Output

At the end









At the beginning