Performance Iterating Generic Lists

There are 3 obvious ways of iterating through each item in a generic list, but which is the most efficient.

1. using a for statement
2. using a foreach statement
3. using the List.ForEach method with a delegate

I created the following simple application to test the differences:

public partial class Form1 : Form
    {
        List items = new List();
        ProfileTimer timer = new ProfileTimer();
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void buttonAllocate_Click(object sender, EventArgs e)
        {
            int itemCount = (int)numericUpDown1.Value;
            textBox1.Clear();
            textBox1.AppendText("Allocating " + itemCount.ToString() + " items.\n");
            items.Capacity = itemCount;
            timer.Start();
            for (int i = 0; i < itemCount; i++)
            {
                items.Add(new ListItem());
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void buttonForLoop_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with for loop\n");
            timer.Start();
            int itemCount = items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                items[i].Value++;
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void ButtonForEachStatement_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with foreach\n");
            timer.Start();
            foreach(ListItem item in items)
            {
                item.Value++;
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void buttonForEachDelegate_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with foreach delegate\n");
            timer.Start();
            items.ForEach(delegate(ListItem item)
                {
                    item.Value++;
                }
            );
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
    }
 
Where the list item is defined as
    class ListItem
    {
        public int Value;
    }

The following results were obtained in Seconds

No of items in the list For Statement ForEach Statement ForEach Delegate
100,000 0.000909729 0.00154351 0.001170701
1,000,000 0.009031616 0.015998993 0.011646201
10,000,000 0.093305468 0.160015975 0.114651431

Tests run on an Intel Pentium Dual Core 3.2GHz with 3Gb Ram.

As we can see the choice of iterator makes very little difference when there are a small amount of items in the list, but as we move upto iterating lists containing hundreds of thousands of items, there are some performance improvements between the methods.

The For statement out performs the rest, 71% faster than the ForEach Statement, but it should be noted that the itemcount check in the for loop needs to be stored and not checked on each iteration. i.e. don’t use for(int i=0; i

The ForEach delegate comes in second, 39% faster than the ForEach Statement.

Conclusion

For most applications there is not much performance impact in the iteration times, but if time is critical or you have nested iterations then you should be using a basic for loop (BUT rememeber to store the limit in an integer and use in the comparison and DONT allocate a new ListItem variable in the iterator).

Personally, having come from a delphi background and tending to use the iterator pattern, I’ll be using the ForEach delegate. I think it reads nicer and gets a reasonable performance.

Posted in c#, Code | Comments Off

How to get the running exe File Version

Nice and simple, get the running assembly, get the AssemblyName details object, get the version property.

Assembly asm =  Assembly.GetExecutingAssembly();
AssemblyName AssDetails = asm.GetName();
String versionAsString = AssDetails.Version.ToString();
Posted in c#, Code | Comments Off

Ext.util.SpriteManager

Original post date May 1st, 2007
One of the ways of improving web page performance (especially in RIA – Rich Internet Applications) where there are lots of small images that need to be displayed, e.g. on a toolbar, is to create a compound image and then use css to select a section of the image to display. In the javascript world this is known as using sprites. In the world of C#/vb/Delphi this is well known and there have always been ImageList components that store images in this form.

So instead of creating single images we create a composite image.

To make the process of assigning the correct css style to select on of the images to display, I have created a SpriteManager addition to Ext JS as follows:

Ext.namespace('Ext', 'Ext.util');
 
Ext.util.SpriteManager = function(config){
        Ext.apply(this,config,{
                spriteSource:true,
                spriteWidth:1,
                spriteHeight:1,
                spriteColumns:1,
                spriteRows:1
                });
};
 
 
Ext.util.SpriteManager.prototype = {
 
    /**
     * Gets the CSS Style for the appropriate image
     * @param {Object...} spriteLocation Expects an object with an X and Y location of the sprite to display
     * @return {String} returns the CSS style string enclosed in braces {}
     */
    getSpriteCSS : function(spriteLocation){
            var locationX = spriteLocation.x-1 || 0;
            var locationY = spriteLocation.y-1 || 0;
            var spriteCss = ['{'];
            var spriteW = this.spriteWidth / this.spriteColumns;
            var spriteH = this.spriteHeight / this.spriteRows;
            var spriteXPos = locationX * spriteW;
            var spriteYPos = locationY * spriteH;
 
            if(!typeof this.spriteSource =="boolean")
            {            
                spriteCss.push('background:url(' + this.spriteSource +');');
            }
            spriteCss.push('height:' + spriteH + 'px;');
            spriteCss.push('width:' + spriteW + 'px;');
            spriteCss.push('background-position:-' + spriteXPos + 'px -' + spriteYPos + 'px;');
            spriteCss.push('}');
            return spriteCss.join("");
    },
 
    /**
     * Applies the CSS Style for the appropriate sprite image to an element
     * @param {element} Ext.Element to apply the sprite style to.
     * @param {Object...} spriteLocation Expects an object with an X and Y location of the sprite to display
     */
        applySpriteCss : function(el, spriteLocation)
        {
            var css = this.getSpriteCSS(spriteLocation);
            el.applyStyles(css);
        }
};

Here is an example of the usage:

<script type="text/javascript">
var spriteManager = new Ext.util.SpriteManager({
            spriteSource:"sprites.png",
            spriteWidth:64,
            spriteHeight:34,
            spriteColumns:4,
            spriteRows:2
            });
</script>
 
...
 
<img id="test" src="images/default/s.gif" /> 
<a href="javascript:spriteManager.applySpriteCss(Ext.get('test'),{x:1,y:1});">Image 1,1</a>
<a href="javascript:spriteManager.applySpriteCss(Ext.get('test'),{x:2,y:1});">Image 2,1</a>
<a href="javascript:spriteManager.applySpriteCss(Ext.get('test'),{x:1,y:2});">Image 1,2</a>
<a href="javascript:spriteManager.applySpriteCss(Ext.get('test'),{x:2,y:2});">Image 2,2</a>
Posted in Code, Javascript | Comments Off

Ext.Format extension for thousands separator formatting

A simple function, the basis of was in the public domain (see comments) to format a number with thousand separators.

Ext.apply(Ext.util.Format,{
    decimalSeparator : '.',
    thousandSeparator : ',',
    /* Adapted from http://www.mredkj.com/javascript/nfbasic.html, 
     * Public Domain, without copyright, and can be used without restriction: 
     * see http://www.mredkj.com/legal.html
     */    
 
    asThousands : function(value)
    {
        value = parseInt(value,10) + '';
        var x = value.split(this.decimalSeparator);
        var x1 = x[0];
        var x2 = x.length > 1 ? this.decimalSeparator + x[1] : '';
        var rgx = /(\d+)(\d{3})/;
        while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + this.thousandSeparator + '$2');
        }
        return x1 + x2;
    }
});
Posted in Code, Javascript | Comments Off

101 of Memory Leak causes in JavaScript

Really nice article explaining some of the gotcha’s that can cause memory leaks in JavaScript

http://www-128.ibm.com/developerworks/web/library/wa-memleak/

Posted in Code, Javascript | Comments Off

Javascript – Rails like pluralize function

Found this on scripts.dzone.com blogged for reference.

*
* This script depends on no outside libraries.
*/
 
Inflector = {
/*
     * The order of all these lists has been reversed from the way 
     * ActiveSupport had them to keep the correct priority.
     */
    Inflections: {
        plural: [
            [/(quiz)$/i,               "$1zes"  ],
            [/^(ox)$/i,                "$1en"   ],
            [/([m|l])ouse$/i,          "$1ice"  ],
            [/(matr|vert|ind)ix|ex$/i, "$1ices" ],
            [/(x|ch|ss|sh)$/i,         "$1es"   ],
            [/([^aeiouy]|qu)y$/i,      "$1ies"  ],
            [/(hive)$/i,               "$1s"    ],
            [/(?:([^f])fe|([lr])f)$/i, "$1$2ves"],
            [/sis$/i,                  "ses"    ],
            [/([ti])um$/i,             "$1a"    ],
            [/(buffal|tomat)o$/i,      "$1oes"  ],
            [/(bu)s$/i,                "$1ses"  ],
            [/(alias|status)$/i,       "$1es"   ],
            [/(octop|vir)us$/i,        "$1i"    ],
            [/(ax|test)is$/i,          "$1es"   ],
            [/s$/i,                    "s"      ],
            [/$/,                      "s"      ]
        ],
        singular: [
            [/(quiz)zes$/i,                                                    "$1"     ],
            [/(matr)ices$/i,                                                   "$1ix"   ],
            [/(vert|ind)ices$/i,                                               "$1ex"   ],
            [/^(ox)en/i,                                                       "$1"     ],
            [/(alias|status)es$/i,                                             "$1"     ],
            [/(octop|vir)i$/i,                                                 "$1us"   ],
            [/(cris|ax|test)es$/i,                                             "$1is"   ],
            [/(shoe)s$/i,                                                      "$1"     ],
            [/(o)es$/i,                                                        "$1"     ],
            [/(bus)es$/i,                                                      "$1"     ],
            [/([m|l])ice$/i,                                                   "$1ouse" ],
            [/(x|ch|ss|sh)es$/i,                                               "$1"     ],
            [/(m)ovies$/i,                                                     "$1ovie" ],
            [/(s)eries$/i,                                                     "$1eries"],
            [/([^aeiouy]|qu)ies$/i,                                            "$1y"    ],
            [/([lr])ves$/i,                                                    "$1f"    ],
            [/(tive)s$/i,                                                      "$1"     ],
            [/(hive)s$/i,                                                      "$1"     ],
            [/([^f])ves$/i,                                                    "$1fe"   ],
            [/(^analy)ses$/i,                                                  "$1sis"  ],
            [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, "$1$2sis"],
            [/([ti])a$/i,                                                      "$1um"   ],
            [/(n)ews$/i,                                                       "$1ews"  ],
            [/s$/i,                                                            ""       ]
        ],
        irregular: [
            ['move',   'moves'   ],
            ['sex',    'sexes'   ],
            ['child',  'children'],
            ['man',    'men'     ],
            ['person', 'people'  ]
        ],
        uncountable: [
            "sheep",
            "fish",
            "series",
            "species",
            "money",
            "rice",
            "information",
            "equipment"
        ]
    },
    ordinalize: function(number) {
        if (11 &lt;= parseInt(number) % 100 &amp;&amp; parseInt(number) % 100 &lt;= 13) {
            return number + "th";
        } else {
            switch (parseInt(number) % 10) {
                case  1: return number + "st";
                case  2: return number + "nd";
                case  3: return number + "rd";
                default: return number + "th";
            }
        }
    },
    pluralize: function(word) {
        for (var i = 0; i &lt; Inflector.Inflections.uncountable.length; i++) {
            var uncountable = Inflector.Inflections.uncountable[i];
            if (word.toLowerCase() == uncountable) {
                return uncountable;
            }
        }
        for (var i = 0; i &lt; Inflector.Inflections.irregular.length; i++) {
            var singular = Inflector.Inflections.irregular[i][0];
            var plural   = Inflector.Inflections.irregular[i][1];
            if ((word.toLowerCase() == singular) || (word == plural)) {
                return plural;
            }
        }
        for (var i = 0; i &lt; Inflector.Inflections.plural.length; i++) {
            var regex          = Inflector.Inflections.plural[i][0];
            var replace_string = Inflector.Inflections.plural[i][1];
            if (regex.test(word)) {
                return word.replace(regex, replace_string);
            }
        }
    }
}
 
function ordinalize(number) {
    return Inflector.ordinalize(number);
}
 
/*
 * Javascript doesnt have optional parameters or overloading so I had to use
 * the ever popular pseudo options hash object technique.
 * required properties:
 *     count    Number of objects to pluralize
 *     singular Singular noun for the objects
 * optional property:
 *     plural   Plural (probably irregular) noun for the objects
 * examples:
 *      pluralize({ count: total_count, singular: "Issue" })
 *      pluralize({ count: total_count, singular: "Goose", plural: "Geese" })
 */
function pluralize(options) {
    return options.count + " " + (1 == parseInt(options.count) ?
        options.singular :
        options.plural || Inflector.pluralize(options.singular));
}
Posted in Code, Javascript | Comments Off

JQuery and human readable email addresses

I’ve just started playing with the power that is Jquery and came up with this nice use for the Ajax functionality in Jquery.

You want to put your email address on your web site so people can contact you, but don’t want to put a mailto: anchor in the html, because it will be spidered and added to some morons Spam list.

Here is a simple and server independent solution:

Firstly, create a file on your site, it doesn’t have to have a html extension, e.g. email.me
In the content of the file, add the html snippet that you would like to display to the user as your email address (usually an anchor tag with a mailto: href). This is the html that will be inserted into your web page when the user clicks on the Show email address text.

e.g.

<a href="mailto:someone@somewhere">someone@somewhere</a>

In your web pages, where you wish someone to be able to see your email address by clicking, enter a span with a class of email.

<span class="email">Click to see email</span>

in the ready function for your document enter the following:

$('.email').click(function(el){
    $(this).hide().load('email.me').fadeIn(1000);
});

This will add a click function to all elements assigned the email class, that when clicked, will replace the current content with the content of the email.me file (faded in :) ). In this case your email mailto anchor. This principle can be used to display any content. Maybe you want to hide the comment form for your blog, until a display has been clicked, give it a try.

Posted in Code, Javascript | Comments Off

OverlayIcon – Displaying overlayed icons in JTree

In companion to the CompoundIcon article, here is a class to allow you to build up icons with overlays that can be used anywhere, but specifically in JTree.

/*
 * (c)2008 mharrison
 * This class is released under GPLv3
 */
package uk.co.lummie.code;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Vector;
import javax.swing.Icon;

public class OverlayedIcon implements Icon {

    private Vector _icons = new Vector();
    private int _spaceSize = 2;

    public OverlayedIcon(Icon[] icons) {
        for (int i = 0; i < icons.length; i++) {
            _icons.add(icons[i]);
        }
    }

    @Override
    public int getIconHeight() {
        int result = 0;
        for (Icon icon : getIcons()) {
            result = Math.max(result, icon.getIconHeight());
        }
        return result;
    }

    @Override
    public int getIconWidth() {
        int result = 0;
        for (Icon icon : getIcons()) {
            result = Math.max(result, icon.getIconWidth());
        }
        return result;
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        int h = getIconHeight();
        int w = getIconWidth();

        for (Icon icon : getIcons()) {
            icon.paintIcon(c, g, x + (w - icon.getIconWidth()) / 2, y + (h - icon.getIconHeight()) / 2);
        }
    }

    public int getSpaceSize() {
        return _spaceSize;
    }

    public void setSpaceSize(int spaceSize) {
        this._spaceSize = spaceSize;
    }

    public void add(Icon icon) {
        _icons.add(icon);
    }

    public Vector getIcons() {
        return _icons;
    }
}
Posted in Code, Java | Comments Off

CompoundIcon – Displaying more than one icon in JTree

I came across the requirement to display more than one Icon against the nodes in a Jtree. After several hours /days of building custom TreeCellRenderers and TreeCellEditors, inspiration hit. The JLabel can only display one icon, so lets override Icon to display more than one icon, but pretend it’s just a single Icon still.

The following Java class implements a CompoundIcon. Simply create an instance of it passing in the array of Icons you wish to be displayed. Use setSpaceSize to change the space between the icons when the are rendered. Use add, to append new icons if needed after the class has been constructed.

The instance can then be used wherever and Icon is needed.

/*
 * (c)2008 mharrison
 * This class is released under GPLv3
 */
package uk.co.lummie.code;
 
import java.awt.Component;
import java.awt.Graphics;
import java.util.Vector;
import javax.swing.Icon;
 
public class CompoundIcon implements Icon {
 
    private Vector _icons = new Vector();
    private int _spaceSize = 2;
 
    public CompoundIcon(Icon[] icons) {
        for (int i = 0; i &lt; icons.length; i++) {
            _icons.add(icons[i]);
        }
    }
 
    @Override
    public int getIconHeight() {
        int result = 0;
        for (Icon icon : getIcons()) {
            result = Math.max(result, icon.getIconHeight());
        }
        return result;
    }
 
    @Override
    public int getIconWidth() {
        int result = 0;
        for (Icon icon : getIcons()) {
            result += icon.getIconWidth();
            result += getSpaceSize();
        }
        return result;
    }
 
    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        int h = getIconHeight();
        int offset = 0;
 
        for (Icon icon : getIcons()) {
            icon.paintIcon(c, g, x + offset, y + (h - icon.getIconHeight()) / 2);
            offset += icon.getIconWidth();
            offset += getSpaceSize();
        }
    }
 
    public int getSpaceSize() {
        return _spaceSize;
    }
 
    public void setSpaceSize(int spaceSize) {
        this._spaceSize = spaceSize;
    }
 
    public void add(Icon icon) {
        _icons.add(icon);
    }
 
    public Vector getIcons() {
        return _icons;
    }
}
Posted in Code, Java | Comments Off

Windows 8 gestures revealled…

image
Turn on usability

image
Enable security

image
Windows Help

image
Blue screen of death (undocumented gesture)

Posted in Misc | Comments Off