Sunday, June 8, 2008

How to optimize html pages if your target is slow networks

These days mobile devices are getting very popular. It is really cool to access internet while you are in middle of no where. Unfortunately the network you use to access the internet is your phone companies network and still they are pretty slow.

If you are developing web sites for mobile devices you have to consider their network capabilities. Making couple of changes on your html code can make your users save tremendous amount of time.

I am planning to write more optimization tips but today I will mention about the line breaks to optimize time.

Following is a html code sample:

<span>Your text here!</span>
<span>Another line</span>

Usually, we put a line break to make code clear and easy to read. Even though you don't see the line break, it is a byte too. Actually, in windows environment it is 2 bytes (\r\n). Line breaks are ignored by html.

So, previous code sample is no different than this:

<span>Your text here!</span><span>Another line</span>

I just saved 1 byte (or 2 bytes in windows machine). Client doesn't have to get these bytes.

It might look like a very minor save but if you think that your site is getting 10,000 hits a day, you do the math!

For example, facebook mobile (http://iphone.facebook.com) can optimize their html code. On the other hand, http://google.com/m is pretty optimized by removing line breaks.

Sunday, June 1, 2008

C# Circular Buffer - First in first out (Not thread safe)

I needed a circular buffer for c# and I couldn't find it on the web. I implemented my version and here it is:

Note: There is no head and tail on this buffer. All you can do is write and read forever. Also, this buffer is not thread safe.

using System;
using System.Collections.Generic;
using System.Text;

namespace Utezduyar.IO.CoreCommunicator
{
    /// <summary>
    /// A circular buffer object.
    /// </summary>
    /// <example>
    /// CircularBuffer<byte> buffer = new CircularBuffer<byte>(3);
    /// buffer.Add(0x41);
    /// buffer.Add(0x42);
    /// buffer.Add(0x43);
    /// buffer.Add(0x44);
    /// buffer.Add(0x45);
    /// 
    /// Console.WriteLine("0:" + buffer.Get(0).ToString("X2"));
    /// Console.WriteLine("1:" + buffer.Get(1).ToString("X2"));
    /// Console.WriteLine("2:" + buffer.Get(2).ToString("X2"));
    /// Console.WriteLine("3:" + buffer.Get(3).ToString("X2"));
    /// Console.WriteLine("4:" + buffer.Get(4).ToString("X2"));
    /// 
    /// // Output:
    /// // 0:45
    /// // 1:44
    /// // 2:43
    /// // 3:45
    /// // 4:44
    /// </example>
    public class CircularBuffer<T>
    {
        private T[] buffer; // Buffer
        private int bufferIndex = 0; // Latest index of the buffer

        /// <summary>
        /// Constructor to initialize the buffer
        /// </summary>
        /// <param name="size">Size of the buffer</param>
        public CircularBuffer(int size)
        {
            // Parameter check
            if (size <= 0)
                throw new ArgumentException("Size must be greater than 0");

            // Assing variables
            buffer = new T[size];
        }

        /// <summary>
        /// Default constructor. Initializes a <c>CircularBuffer</c>
        /// that can hold 256 items in it.
        /// </summary>
        public CircularBuffer() : this (256)
        { 
        
        }

        /// <summary>
        /// Returns the size of the buffer
        /// </summary>
        /// <remarks>
        /// This function returns only the size of the buffer.
        /// This function can not be used to determine how 
        /// many bytes are in the buffer.
        /// </remarks>
        public int Length
        {
            get
            {
                return this.buffer.Length;
            }
        }

        /// <summary>
        /// Adds one item to the next available place in the buffer
        /// </summary>
        /// <remarks>
        /// If the buffer is full, it overwrites 
        /// the very first item.
        /// </remarks>
        /// <param name="item">Item to add</param>
        public void Add(T item)
        {
            if (bufferIndex == this.Length)
                bufferIndex = 0;

            buffer[bufferIndex++] = item;
        }

        /// <summary>
        /// Used to retrieve item array from the buffer.
        /// </summary>
        /// <param name="numberOfItems">Number of items needed.</param>
        /// <returns>Array of the item type. The array lenght 
        /// is same as <c>numberOfItems</c>.
        /// </returns>
        public T[] GetItems(int numberOfItems)
        {
            // Check arguments
            if (numberOfItems <= 0)
                throw new ArgumentException("numberOfItems needs to be greater than zero");

            // Create the byte buffer. This byte buffer will be returned
            T[] items = new T[numberOfItems];

            // Get bytes from buffer
            for (int i = 0; i < numberOfItems; i++)
                items[i] = Get(i);

            // Return
            return items;
        }

        /// <summary>
        /// Returns latest byte from buffer
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        /// <example>
        /// CircularBuffer b = new CircularBuffer(10);
        /// b.Add(0x41);
        /// b.Add(0x42);
        /// b.Get(0); // This would be 0x42
        /// b.Get(1); // This would be 0x41
        /// </example>
        public T Get(int index)
        { 
            // Argument check
            if (index < 0)
                throw new ArgumentException("Index must be greater than or equal to zero");

            if (this.Length <= 0)
                throw new ArgumentException
                    (string.Format("Buffer size is {0}. Buffer needs to be greater than 0", this.Length));

            // Algorithm to find the buffer index
            index = index % this.Length;
            if (index < bufferIndex)
                index = bufferIndex - index - 1;
            else
                index = bufferIndex - index - 1 + this.Length;            

            // Return the item
            return buffer[index];
        }
    }
}