A simple performance test for comparing direct file property access or creating a FileInfo object.

The results show that if you are accessing more then one file property FileInfo is the way to go otherwise File.GetCreationTime and related methods have the same performance hit.

100 iterations of c:\windows
directValues –> 00:00:00.2900065
infoValues –> 00:00:00.1611554

void Main()
{
    var folder = "c:\\windows";
    var files = Directory.GetFiles(folder, "*.*", SearchOption.TopDirectoryOnly);

    var stopwatch = new Stopwatch();
    var directValues = 0l;
    var infoValues = 0l;
    for (int i = 0; i < 100; i++)
    {
        stopwatch.Restart();
        stopwatch.Start();
        foreach (var file in files)
        {
            var lastWriteTime = File.GetLastWriteTime(file);
            var creationTime = File.GetCreationTime(file);
        }

        stopwatch.Stop();
        directValues += stopwatch.ElapsedTicks;

        stopwatch.Restart();
        stopwatch.Start();
        foreach (var file in files)
        {
            var info = new FileInfo(file);
            var lastWriteTime = info.LastWriteTime;
            var creationTime = info.CreationTime;
        }

        stopwatch.Stop();
        infoValues += stopwatch.ElapsedTicks;

    }

    "100 iterations of c:\\windows".Dump();
    TimeSpan.FromTicks(directValues).Dump("directValues");
    TimeSpan.FromTicks(infoValues).Dump("infoValues");
}

// <copyright>
//   Copyright (c) 2012 Codefarts
//   All rights reserved.
//   contact@codefarts.com
//   http://www.codefarts.com
// </copyright>

namespace Codefarts.ObjectPooling
{
    using System;

    /// <summary>
    /// Provides a generic object pooling manager.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectPoolManager<T> where T : class
    {
        /// <summary>
        /// Holds a reference to a singleton instance.
        /// </summary>
        private static ObjectPoolManager<T> instance;

        /// <summary>
        /// Used to track the number of items that have been pushed to the pool.
        /// </summary>
        private int count;

        /// <summary>
        /// Holds the pooled item references.
        /// </summary>
        private T[] cachedItems = new T[10000];


        /// <summary>
        /// Gets or sets the creation callback.
        /// </summary>
        public Func<T> CreationCallback { get; set; }

        /// <summary>
        /// Gets the number of items in the pool.
        /// </summary>
        public int Count
        {
            get
            {
                return this.count;
            }
        }

        /// <summary>
        /// Pops a item from the pool.
        /// </summary>
        /// <returns>A pooled object reference.</returns>
        /// <exception cref="System.NullReferenceException">'CreationCallback' property must be set if you try to pop a item and there are no items available.</exception>
        public T Pop()
        {
            // lock here to prevent treading conflicts with array manipulation
            lock (this.cachedItems)
            {
                // check if there are any pooled objects
                if (this.count < 1)
                {
                    // check if creation callback is null
                    if (this.CreationCallback == null)
                    {
                        throw new NullReferenceException("'CreationCallback' property must be set if you try to pop a item and there are no items available.");
                    }

                    // there are no available objects so create a new one.
                    return this.CreationCallback();
                }

                // reduce the count
                this.count--;

                // retrieve the item and return it
                return this.cachedItems[this.count];
            }
        }

        /// <summary>
        /// Pushes the specified value.
        /// </summary>
        /// <param name="value">The value to push into the pool.</param>
        public void Push(T value)
        {
            // lock here to prevent treading conflicts with array manipulation
            lock (this.cachedItems)
            {
                // update the count
                this.count++;

                // if we need more room for storage increase the size of the cache array
                if (this.count > this.cachedItems.Length)
                {
                    Array.Resize(ref this.cachedItems, this.cachedItems.Length * 2);
                }

                // store the value 
                this.cachedItems[this.count - 1] = value;
            }
        }

        /// <summary>
        /// Gets the singleton instance of the class.
        /// </summary>
        public static ObjectPoolManager<T> Instance
        {
            get
            {
                return instance ?? (instance = new ObjectPoolManager<T>());
            }
        }
    }
}

And some unit tests to go along with it.

// <copyright>
//   Copyright (c) 2012 Codefarts
//   All rights reserved.
//   contact@codefarts.com
//   http://www.codefarts.com
// </copyright>

namespace Codefarts.Tests.ObjectPooling
{
    using System;

    using Codefarts.ObjectPooling;

    using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;

    [TestClass]
    public class ObjectPoolingManagerTests
    {
        ObjectPoolManager<TestObject> manager;

        [TestInitialize]
        public void Setup()
        {
            this.manager = new ObjectPoolManager<TestObject>();
        }

        [TestCleanup]
        public void Cleanup()
        {
            this.manager = null;
        }

        public class TestObject
        {
            public string stringValue;
            public int intValue;
        }

        [TestMethod]
        public void Pop_With_Empty_Pool_NoCallback()
        {
            try
            {
                var item = this.manager.Pop();
                Assert.IsNotNull(item);
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is NullReferenceException);
            }
        }

        [TestMethod]
        public void Pop_With_Empty_Pool_WithCallback()
        {
            try
            {
                this.manager.CreationCallback = this.Callback;
                var item = this.manager.Pop();
                Assert.IsNotNull(item);
                Assert.AreEqual(0, item.intValue);
                Assert.AreEqual(null, item.stringValue);
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is NullReferenceException);
            }
        }

        private TestObject Callback()
        {
            return new TestObject();
        }

        [TestMethod]
        public void Push_Object()
        {
            try
            {
                Assert.AreEqual(0, this.manager.Count);
                this.manager.Push(new TestObject());
                Assert.AreEqual(1, this.manager.Count);
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.ToString());
            }
        }

        [TestMethod]
        public void Push_Pop_Objects()
        {
            try
            {
                Assert.AreEqual(0, this.manager.Count);
                for (var i = 0; i < 3; i++)
                {
                    this.manager.Push(new TestObject() { stringValue = "Item" + i, intValue = i });
                }

                Assert.AreEqual(3, this.manager.Count);

                for (var i = 3 - 1; i >= 0; i--)
                {
                    var item = this.manager.Pop();
                    Assert.AreEqual(i, item.intValue);
                    Assert.AreEqual("Item" + i, item.stringValue);
                }

                Assert.AreEqual(0, this.manager.Count);
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.ToString());
            }
        }
    }
}

The funny thing about brain disorders is that they affect the one part of your body that you are unable to perceive as being afflicted with something. Kind of like how crazy people don’t know there crazy.

When trying to come up with a name for this disorder I asked stack exchange and got a number of helpful responses. Everything from Analysis paralysis to having a Rube Goldberg mentality.

No matter what I do, I can't help but overcomplicate almost every piece of code/application I write. My mind automatically jumps to thoughts of 'OK, I'll need to write this, this, this, and this, and I'll need to make sure to use a repository and MVVM patterns, utilize this and that library' etc. An hour of coding later and it's already spiraling out of control with features & settings that don't need to be there.

This last week I have recently been spending some time on my old WowTracks.com website, in particular the data acquisition utilities needed to capture and store the World of Warcraft armory data. I started by thinking about what kind of app I needed and where it was going to be run. I considered writing it in Unity3D first so that I could port the application to multiple platforms, but unity’s GUI system is too much of a hassle when it comes to presenting large amounts of complex data. I also considered a win forms app, Windows store/Metro, WPF, Silverlight, or even a console application.

I ended up starting to write it as a console application thinking that I did not need to do anything fancy just create a app that schedules downloads of armory url’s at specified intervals. Didn’t take long for me to realize that a console app was not going to cut it.

I then started to write it as a win forms app only to discover that the data binding was severely lacking compared to WPF and I would have to do a lot of manual coding. After scrapping the win forms app in favor of a WPF app things were going fine until I ran into a little issue with my PC randomly freezing up for one second at a time then unfreezing for one second and repeating until I restarted my computer. At first it was confusing because even after managing to get visual studio to quit my system seemed fine but when I mouse over a link in a web browser (IE, Firefox, Chrome) would cause the system to start locking up for one second intervals again.

Initially it seemed like a virus or hacker got into my system as it was only affecting browser applications but from doing some internet searches it seems there is a huge bug with .net 4.0 and WPF. Something to do with UI automation and large complicated visual element trees causing WPF to cause a system to lockup and slow down. This did not bode well for writing the application in WPF.

*sigh* back to writing the app in win forms again. /rollseyes

After a week of back and fourth and nothing to really show for it, most of the time I spent and code I wrote got me further and further away from the end goal. Which leads me the title of this post. I have self diagnosed Anal-para-complica-tard-isis syndrome.  In other words I suffer from analysis paralysis complicatardation with acute over engineering retarex.

Definitions:
Complicatardation (n.) "someone who is retardedly over-complicated"
Retarex (adj.) "something that is complex to a retarded degree."
Portmanteau “a combination of two (or more) words or morphemes, and their definitions, into one new word.”

PS: You see what I did thar? :P


Some .net/mono frameworks do not support the 3 argument GetDirectories method. The code below provides a simple replacement.

/// <summary>
/// Builds an array of folders & sub folders.
/// </summary>
/// <param name="path">The path to search.</param>
/// <param name="pattern">The search string to match against the names of files in path. The parameter cannot end in two periods 
/// ("..") or contain two periods ("..") followed by System.IO.Path.DirectorySeparatorChar or System.IO.Path.AltDirectorySeparatorChar,
/// nor can it contain any of the characters in System.IO.Path.InvalidPathChars.
///</param>
/// <param name="searchOptions">One of the System.IO.SearchOption values that specifies whether the search operation should include 
/// all subdirectories or only the current directory.
///</param>
/// <returns>A String array of directories that match the search pattern.</returns>
public static string[] GetDirectories(string path, string pattern, SearchOption searchOptions)
{
    // check if searching for all directories
    if (searchOptions == SearchOption.AllDirectories)
    {
        // add start paths to list
        var list = Directory.GetDirectories(path, pattern);
        var index = 0;
        var count = list.Length;

        // process list and add folders to end of list
        while (index < count)
        {
            var directories = Directory.GetDirectories(list[index++], pattern);
            if (directories.Length > 0)
            {
                // check if we need more space to store the directories
                if (count + directories.Length > list.Length - 1)
                {
                    Array.Resize(ref list, list.Length + directories.Length + 1000);
                }

                // add directories to end of the list
                foreach (var directory in directories)
                {
                    list[count++] = directory;
                }
            }

            // trim unused index from end of the array
            if (list.Length > count)
            {
                Array.Resize(ref list, count);
            }
        }

        return list;
    }

    // just return initial list of folder with no sub folders
    return Directory.GetDirectories(path, pattern);
}

I have created a tool to assit in creating materials from tiles in a tile set. See the Tile Material Creation Window page for *.unitypackage download and more information.


Are you working on a large project but dislike how many objects you have to weed through in the hierarchy window? You can create editor scripts that change the objects Object.hideFlags property to hide or show the object in the hierarchy window.

var item = Selection.activeGameObject;
if ((item.hideFlags & HideFlags.HideInHierarchy) == HideFlags.HideInHierarchy)
{
                item.hideFlags = item.hideFlags ^ HideFlags.HideInHierarchy;
                item.active = !item.active;
                item.active = !item.active;
}

Notice that item.active = !item.active is specified twice. Currently in unity 3.5 you need those 2 lines of code for the game object to hide and show properly in the hierarchy window.


If your suddenly finding that Unity will instanty terminate while running your code, check if you are invoking any infinite recusion loops. This has recently happened to me and it was a bit of a pain to track down with Unity 3.5 instantly terminating. Hopfully the Unity team will handle the infinite recustion issue in a future version.


You can visually tag your game objects with icons by selecting the object and clicking the Red/Green/Blue colored cube in the upper left of the inspector window.

You can select a colored Label, Dot, or a Texture from your assets.


I have still been learning the in and outs of Unity for the past few weeks. I've been thinking that because I have not been making any regular posts on this site that I would start posting a series of quick unity tips as I learn of them.

Tip #1 - Prevent config dialog from showing when running your compiled game.

When you build your unity game using "File -> Build & Run" and then run the *.exe that was generated you will see a dialog pop up.

To prevent the configuration window from being shown select "File -> Build Settings..." in unity and click the "Player Settings" button at the bottom of the window. The Unity inspector window will contain a number of options. Find the drop down titled "Display Resolution Dialog" and set it to "Disabled". Rebuild your game and run the generated *.exe. No more dialog pop up!


Zider Revisited

Published 9/11/2011 by createdbyx in News | Programming

I've been making numerous updates to my Zider project over at codeplex. Other then that I have not been getting much done programming wise, been busy with other things.


Created by: X

Just another personal website in this crazy online world

Name of author Dean Lunz (aka Created by: X)
Computer programming nerd, and tech geek.
About Me -- Resume