Что быстрее и удобнее: Hashtable или Dictionary()? - PullRequest
1 голос
/ 23 октября 2010

Преамбула: я работаю с сильно загруженным приложением, которое создает большие массивы данных.

Я написал следующий класс

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

    namespace CSharpSampleApplication.Data.CoreObjects
    {
        [Serializable]
        public class CalcItem
        {
            public CalcItem()
            {
                _additional = new Hashtable();
            }

            private readonly Hashtable _additional;

            public bool ContainsKey(int id)
            {
                return _additional.ContainsKey(id);
            }

            public void Add(int id, double value)
            {
                _additional.Add(id, value);
            }

            public DateTime Date { get; set; }

            public object this[int id]
            {
                get
                {
                    return _additional[id];
                }
            }
        }


    }

Затем в другом классе я создал менеджер, который содержит следующее:

    public List<CalcItem> CalcItems{ get; private set;}
    private readonly Dictionary<string, int> _keys;
    private int _index;
    private readonly object  _lock = new object();

    public int GetIndex(string key)
    {
        lock (_lock)
        {
            if (_keys.ContainsKey(key))
                return _keys[key];
            else
            {
                _index++;
                _keys.Add(key, _index);
                return _index;
            }
        }
    }

Используя эти классы, я регистрирую некоторыеданные в реальном времени, например, такие:

                var clc = new CalcItem();
                clc.Date = DateTime.Now;
                clc.Add(_calcItemManager.GetIndex("testData"), r.Next() / 100.00);
                clc.Add(_calcItemManager.GetIndex("testData1"), r.Next() / 100.00);

                i++;

                if (i % 25 == 0)
                {
                    clc.Add(_calcItemManager.GetIndex("testData2"), r.Next()/100.00);
                    clc.Add(_calcItemManager.GetIndex("testData3"), r.Next()/100.00);
                    clc.Add(_calcItemManager.GetIndex("testData4"), r.Next()/100.00);
                    clc.Add(_calcItemManager.GetIndex("testData5"), r.Next()/100.00);
                }
                _calcItemManager.Add(clc);

Таким образом, менеджер сохраняет привязки [строковый ключ] - [int index] для всех calcItems.

Вопрос: лучше лииспользовать Dictionary<int, double> вместо Hashtable () для оптимизации использования памяти и ускорения работы?Элементы списка - содержит около 1.000.000 записей. CalcItem.Additional - содержит около 5 - 10 записей

Ответы [ 3 ]

5 голосов
/ 23 октября 2010

Единственный способ ответить «быстрее» - это рассчитать время для ваших типичных данных. Тем не менее, словарь более удобный (не нужно разыгрывать) и эффективный (без бокса).

Если ключи данных смежные , однако, было бы лучше просто использовать List-of-double и использовать ключ в качестве индекса (со смещением, если ваши данные не начинаются с 0).

1 голос
/ 23 октября 2010

Я думаю, что принятый ответ на этот вопрос StackOverflow также отвечает на ваш вопрос.

Короче говоря, обе структуры данных будут иметь очень похожую производительность в большинстве ситуаций. Если это важно для вас, вы можете (и должны) измерить.

0 голосов
/ 23 октября 2010

Марк Гравелл - потрясающее решение с List-of-double !!! Как я мог пропустить это ?! Память уменьшена вдвое! Вот мой новый код:

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

    namespace CSharpSampleApplication.Data.CoreObjects
    {
        [Serializable]
        public class CalcItem
        {
            public CalcItem()
            {
                _additional = new List<double>();
            }

            private readonly List<double> _additional;

            public bool ContainsKey(int id)
            {
                return _additional.Count - 1 >= id;
            }

            public void Add(int id, double value)
            {
                if(ContainsKey(id))
                    _additional[id] = value;
                else
                {
                    while (!ContainsKey(id))
                    {
                        _additional.Add(0);
                    }
                    _additional[id] = value;
                }
            }

            public DateTime Date { get; set; }

            public object this[int id]
            {
                get
                {
                    return _additional[id];
                }
            }
        }


    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...