#Google Analytic Tracker

Pages

Jan 17, 2009

Installed XP on my MacBook Using Boot Camp Assistance and Fails to Boot (hal.dll is missing)

Ok, so recently I got a new machine:Apple MacBook Pro. Its aluminium body felt very solid and I really like its design. Another reason I brought a Mac is because I want to open my eyes to other OS design.

Anyhow, I am not going to pass any judgement on which OS is better until I get use to Mac OS X Leopard (I am waiting for Snow Leopard's OpenCL). Instead, I would like to share my experience on install XP using BootCamp.

RTFM!

Yes, I was being naïve. I didn't read the manual or the guideline before I install XP using Boot Camp. I end up having a hal.dll is missing when trying to boot XP. In fact, I didn't even know how to get into the boot menu to book Mac OS X.

Missing hal.dll Reason

According to this website, it explains why XP failed to boot due to missing hal.dll. However the main reason is that:

After Boot Camp created a FAT32 Partition and start installing XP. I manually deleted the FAT32 partition and broke it down into two partition. I was hoping to have a NTFS for Windows and a small FAT32 for write sharing.

Bad Idea!!! It turns out that Boot Camp doesn't support more than one Windows Partition. I am sure it is possible to do so, but I am not going to spend time investigate how. There are many blogs and websites explains how they are able to create multi-partition for booting more than just XP and Mac OS X.

Solution

Remember these first:

Restart the MacBook - holds the power button for 8 sec.

Eject the CD - holds the "Eject" key that locates on the top right concern of your MacBook before the white boot screen

Boot from CD - hold the "C" key before the white boot screen

Boot menu - hold the "Option (alt)" key before the white boot screen

The way that I fixed the problem is to go to the boot menu and startup Mac OS X. Once you are back Mac OS X, run Boot Camp.  Once it starts, read the Boot Camp Guideline first. It explains exactly what you should or should not do. Anyhow, when you hit continue, you You will have to option to restore the harddrive in one partition, it is a nice feature.

Once you get your partition restore, now you can do the reinstallation. However, this time, don't create or delete any partition.

Jan 14, 2009

Counting Items using Linq vs IEnumable Looping Performance

What is Linq?

If you happened to be a .NET developer and bumped into this blog somehow, you probably already know a bit or heard about Linq is about. Linq, or Language INtegrated Query, is an set of extension to the .NET Framework.  It provides the query-liked syntax and class libraries for querying data. There are many information about Linq, so I won't go further on what Linq is about and how awesome it is.

IEnumerable

There are many collection classes you can find inside .NET Framework.

Eamples:

System.Collections ArrayList
  Queue
  SortedList
  Stack
System.Collections.Generic Dictionary<TKey, TValue>
  List<T>
System.Core HashSet<T>

In the end, you will find all these collection supports IEnumerable, or IEnumerable<T>. These interfaces only have one method: GetEnumerator(), and this method returns System.Collections.IEnumerator or System.Collections.Generic.IEnumerator<T> respectively.

IEnumerator

An IEnumerator object allows you to walk though the collection one by one. It has these methods:

    • MoveNext()
    • Reset()

and a property calls Current

After you get a IEnumerator object, you can call the MoveNext() and get the item from the collection from the Current property.

How to Count

When counting the number of items in a collection using IEnumerator, you could do the following:

[Test]
public void CountTest_UsingIEnumerator()
{
    IEnumerator l_oEnumerator = m_aSampleData.GetEnumerator();
    
    int l_nItemCount = 0;
    while(l_oEnumerator.MoveNext())
    {
        l_nItemCount++;
    }
    
    Trace.WriteLine(string.Format("Number of item in the array: {0}", l_nItemCount));
}

Of course, that is pretty stupid and looks very inefficient, because we could have just do the following:

[Test]
public void CountTest_UsingLength()
{
    int l_nItemCount = m_aSampleData.Length;
    Trace.WriteLine(string.Format("Number of item in the array {0}", l_nItemCount));
}

For an array, there is a length property, you could have just access this property to get the size. However, with Linq, you can also do this too:

[Test]
public void CountTest_UsingLinq()
{
    int l_nItemCount = ((IEnumerable<int>)m_aSampleData).Count();
    Trace.WriteLine(string.Format("Number of item in the array {0}", l_nItemCount));
}

Casting to IEnumerable isn't necessary, but I just want to show you my point that the .Count() is based on the interface.

Count Performance

During a code review, my collegue was concerned that calling Linq Count() method would be a lot slower than just access the Length property directly. When you look at Linq's Count() method, you will notice that it is an extension method. The signature:
public static int Count<TSource>(this System.Collections.Generic.IEnumerable<TSource> source)
indicates the method takes in a IEnumerable<T>, which means it only has 2 method, MoveNext() and Reset.

Does that mean calling the extension Count() is slower then getting the value from the .Length property?

While let do some tests:

Performance Test Using Length Property

[Test]
public void CountPerformanceTest_UsingLength()
{
    int l_oQueryCount = 1000000;

    long l_nStartTick = DateTime.Now.Ticks;
    for(int i=0; i< l_oQueryCount ; i++)
    {
        int l_nCount = m_aSampleData.Length;
    }
    long l_nEndTick = DateTime.Now.Ticks;

    Trace.WriteLine(string.Format("It takes {0} to count {1} times using .Length property.", new TimeSpan(l_nEndTick - l_nStartTick), l_oQueryCount));
}

Performance Test Using Linq Count

[Test]
public void CountPerformanceTest_UsingLinq()
{
    int l_oQueryCount = 1000000;

    long l_nStartTick = DateTime.Now.Ticks;
    for (int i = 0; i < l_oQueryCount; i++)
    {
        int l_nCount = m_aSampleData.Count();
    }
    long l_nEndTick = DateTime.Now.Ticks;

    Trace.WriteLine(string.Format("It takes {0} to count {1} times using .Count() method.", new TimeSpan(l_nEndTick - l_nStartTick), l_oQueryCount));
}

The results:

  • It takes 00:00:00 to count 1000000 times using .Length property.
  • It takes 00:00:00.4218723 to count 1000000 times using .Count() method.

So, pretty much using .Length that no time, or it could be optimized by the compiler or the CPU optimized its execution path. However, calling the .Count() takes a bit of overhead, compare accessing the Length property. What about if I loop though the data and count it?

Performance Test By Looping using IEnumerator

[Test]
public void CountPerformanceTest_UsingEnumerator()
{
    int l_oQueryCount = 10000;
    IEnumerator l_oEnumerator = m_aSampleData.GetEnumerator();

    long l_nStartTick = DateTime.Now.Ticks;
    for (int i = 0; i < l_oQueryCount; i++)
    {

        int l_nItemCount = 0;
        while (l_oEnumerator.MoveNext())
        {
            l_nItemCount++;
        }

        l_oEnumerator.Reset();
    
    }
    long l_nEndTick = DateTime.Now.Ticks;

    Trace.WriteLine(string.Format("It takes {0} to count {1} times by looping though item using the Enumerator", new TimeSpan(l_nEndTick - l_nStartTick), l_oQueryCount));
}

The results:

  • It takes 00:00:07.9843239 to count 10000 times by looping though item using the Enumerator. Note that the test takes more than 7 sec just to query 10,000 times compare with query 0.4 sec for 1,000,000 times using Linq.

Conclusion

So, it appears that the Linq Count() does something else , because we know that looping though the array is extreme slow. So I decided to disassemble the Count() code using reflector:

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<TSource> is2 = source as ICollection<TSource>;
    if (is2 != null)
    {
        return is2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}

Ah,it turns out that Count() takes into account of a ICollection. An array "[]" is basically an array object after it is boxed. Array's base type is IList and ICollection. That means its performance is fairly comparable to just access the Length property. Therefore, you shouldn't be too worry about using the Linq Count(). Linq also some with other methods such as First() and Last(). It makes reading the code much easier when want using meaning method name instead of accessing the item though index. For example, arrayA[arrayA -1] vs arrayA.Last().

 

Jan 1, 2009

Running PHP on IIS 5 => "The specified module could not be found."

Ok, there are enough PHP installation guides on the web. Therefore I am not going to write a full guide and step for install the PHP server. Instead, I would like to share my experience when installing PHP with IIS. This is my first time to setup a PHP web sever on my computer, and I encountered the following 3 problems:

  1. When I run "php-5.2.8-win32-installer.msi", it failed to install : "There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor".
  2. After successfully installed PHP and the ISS ISAPI Module, I either got an Access Denied Problem
  3. In another installation attempt, I got this "The specified module could not be found" message.

Solution

  1. Without going into detail. This is how I solved the issue:
  2. When installing the msi: Install it in C:\PHP, DO NOT use the "Program File" as default and  DON'T select Web Sever.
    1. The reason is that IIS 5 doesn't like space character when mapping the PHP dll. Even if you put quotation for your path, you may still encounter "The specified module could not be found" message when opening a PHP page.
  3. Select the "Don't Install web server" option.  I tried to install "IIS ISAPI Module" and it didn't work for me.
  4. Once PHP is installed, restart your computer.
  5. (Here is where I am not sure why I was able to install the IIS ISAPI Module, but this is what I did)
    1. Download the PHP5 source code.
    2. Copy the php5isapi.dll to the PHP directory
    3. Manually setup the IIS - PHP mapping (Follow the instruction from this link)
    4. Run the msi installer again, run the Repair. It is suggested by the PHP install.txt file (find in C:\PHP\) that running the Repair may fix the issue when installing web server extension.
    5. Afterward, it may ask you to restart your computer.
    6. Run the msi installer one more time, click Change, and select IIS ISAPI Module this time.
    7. You should now able to install the IIS ISAPI module properly.
  6. Now, if you have try to open a php page, you may have an page access denied error.
  7. Go to the C:\PHP\ property
  8. Go to Security
  9. Click Add, and add "Internet Guest Account" and give read access for this user. This properly allows IIS web user access the php ISAPI module.

Conclusion

Since I am not exposing my web server to Internet, I am not worry security. I only use the web server to test some PHP pages.  You probably want to do some researches to see if you need to add the "Internet Guest Account" to the PHP installation directory.