如何在C#中测量HashTable的性能?

时间:2009-08-19 22:46:23

标签: c# performance list comparison hashtable

我正在玩C#集合,我决定编写一个快速测试来衡量不同集合的性能。

我的表现测试是这样的:

int numOps= (put number here);
long start, end, numTicks1, numTicks2;
float ratio;

start = DateTime.Now.Ticks;

for(int i = 0; i < numOps; i++)
{
  //add two elements to collection #1
  //remove one element from collection #1
}

end = DateTime.Now.Ticks;

numTicks1 = end - start;


start = DateTime.Now.Ticks;

for(int i = 0; i < numOps; i++)
{
  //add two elements to collection #2
  //remove one element from collection #2
}

end = DateTime.Now.Ticks;

numTicks2 = end - start;

ratio = (float)numTicks2/(float)numTicks1;

然后我使用不同的集合比较比率值和numOps的不同值来比较它们的比较。

问题有时当我使用足够小的数字(numOps = 500)时,Hashtable和List之间的测试结果是零星的(换句话说,它是一个硬币翻转,其中一个更快)。任何人都可以解释为什么会这样吗?

编辑:谢谢大家!秒表就像魅力一样。

4 个答案:

答案 0 :(得分:8)

尝试查看StopWatch课程,而不是使用 DateTime

此示例直接来自MSDN

    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    Thread.Sleep(10000); //your for loop
    stopWatch.Stop();
    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine(elapsedTime, "RunTime");

答案 1 :(得分:4)

我首先尝试使用更高分辨率的计时器。

关于计时器已有很多问题和答案。

这里有one answer,其中包含您可以使用的选项列表。

请特别查看System.Diagnostics.Stopwatch

答案 2 :(得分:2)

诊断时间的正确方法是迭代运行代码多次(使得总时间是您使用的任何计时机制的分辨率的倍数)然后除以迭代次数以获得准确的时间估计。

秒表返回未量化15 ms的时间,因此显然更适合于计时事件。

答案 3 :(得分:0)

我使用以下代码使用三种不同的Dictionary实现来测试GetHash的性能:

    class TestGetHash
    {
        class First
        {
            int m_x;
        }
        class Second
        {
            static int s_allocated = 0;
            int m_allocated;
            int m_x;
            public Second()
            {
                m_allocated = ++s_allocated;
            }
            public override int GetHashCode()
            {
                return m_allocated;
            }
        }
        class Third
        {
            int m_x;
            public override int GetHashCode()
            {
                return 0;
            }
        }

        internal static void test()
        {
            testT<First>(100, 1000);
            testT<First>(1000, 100);
            testT<Second>(100, 1000);
            testT<Second>(1000, 100);
            testT<Third>(100, 100);
            testT<Third>(1000, 10);
        }

        static void testT<T>(int objects, int iterations)
            where T : new()
        {
            System.Diagnostics.Stopwatch stopWatch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < iterations; ++i)
            {
                Dictionary<T, object> dictionary = new Dictionary<T, object>();
                for (int j = 0; j < objects; ++j)
                {
                    T t = new T();
                    dictionary.Add(t, null);
                }
                for (int k = 0; k < 100; ++k)
                {
                    foreach (T t in dictionary.Keys)
                    {
                        object o = dictionary[t];
                    }
                }
            }
            stopWatch.Stop();
            string stopwatchMessage = string.Format("Stopwatch: {0} type, {1} objects, {2} iterations, {3} msec", typeof(T).Name, objects, iterations, stopWatch.ElapsedMilliseconds);
            System.Console.WriteLine(stopwatchMessage);

            stopWatch = System.Diagnostics.Stopwatch.StartNew();
            for (int i = 0; i < iterations; ++i)
            {
                Dictionary<T, object> dictionary = new Dictionary<T, object>();
                for (int j = 0; j < objects; ++j)
                {
                    T t = new T();
                    dictionary.Add(t, null);
                }
            }
            stopWatch.Stop();
            stopwatchMessage = string.Format("Stopwatch (fill dictionary): {0} type, {1} objects, {2} iterations, {3} msec", typeof(T).Name, objects, iterations, stopWatch.ElapsedMilliseconds);
            System.Console.WriteLine(stopwatchMessage);

            {
                Dictionary<T, object> dictionary = new Dictionary<T, object>();
                for (int j = 0; j < objects; ++j)
                {
                    T t = new T();
                    dictionary.Add(t, null);
                }
                stopWatch = System.Diagnostics.Stopwatch.StartNew();
                for (int i = 0; i < iterations; ++i)
                {
                    for (int k = 0; k < 100; ++k)
                    {
                        foreach (T t in dictionary.Keys)
                        {
                            object o = dictionary[t];
                        }
                    }
                }
                stopWatch.Stop();
                stopwatchMessage = string.Format("Stopwatch (read from dictionary): {0} type, {1} objects, {2} iterations, {3} msec", typeof(T).Name, objects, iterations, stopWatch.ElapsedMilliseconds);
                System.Console.WriteLine(stopwatchMessage);
            }
        }
    }