提高集合的添加性能

eli*_*ias 0 c# collections performance

我正在实施我的收藏:

SpecialCollection类:

public class SpecialCollection<TId, TName, TValue> : Dictionary<CompositeKey<TId, TName>, TValue>
    {

        #region Private fileds

        private Dictionary<CompositeKey<TId, TName>, TValue> _baseDictionary = null;
        private ReaderWriterLockSlim _readWriteLockSlim = new ReaderWriterLockSlim();

        #endregion

        #region Constructors

        public SpecialCollection()
        {
            _baseDictionary = new Dictionary<CompositeKey<TId, TName>, TValue>();
        }

        #endregion

        public void Add(CompositeKey<TId, TName> compositeKey, TValue value)
        {
            _readWriteLockSlim.EnterWriteLock();

            try
            {
                _baseDictionary.Add(compositeKey, value);
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            catch (ArgumentException ex)
            {
                throw ex;
            }
            finally
            {
                _readWriteLockSlim.ExitWriteLock();
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

CompositeKey类:

public struct CompositeKey<TId, TName> : IEquatable<Tuple<TId, TName>>
    {
        public TId Id;
        public TName Name;

        public CompositeKey(TId id, TName name)
        {
            Id = id;
            Name = name;
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            if (this.GetType() != obj.GetType())
                return false;

            return AreEqual(this, (CompositeKey<TId, TName>)obj);
        }

        public bool Equals(CompositeKey<TId, TName> other)
        {
            return AreEqual(this, other);
        }

        private static bool AreEqual(CompositeKey<TId, TName> a, CompositeKey<TId, TName> b)
        {
            if (!a.Id.Equals(b.Id))
                return false;

            if (!a.Name.Equals(b.Name))
                return false;

            return true;
        }

        public static bool operator == (CompositeKey<TId, TName> a, CompositeKey<TId, TName> b)
        {
            return AreEqual(a, b);
        }

        public static bool operator != (CompositeKey<TId, TName> a, CompositeKey<TId, TName> b)
        {
            return !AreEqual(a, b);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode() ^ Name.GetHashCode();
        }

        public bool Equals(Tuple<TId, TName> other)
        {
            throw new NotImplementedException();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我遇到了一个与表现有关的问题.例如,向我的集合添加10000个元素需要9745几毫秒.但是向ConcurrentDictionary添加10000个元素需要4965几毫秒.

如果将30000个元素添加到我的集合中,则需要花费大量时间 - 大约40000几毫秒.

我不知道如何提高性能:(如果有可能,你能告诉我如何改善我的收藏的性能?可能是,与CompositeKey类相关的性能?

编辑:

我测试了这样的性能:

ConcurrentDictionary<CompositeKey<int, int>, int> cd = new ConcurrentDictionary<CompositeKey<int, int>, int>();
            SpecialCollection<int, int, int> sc = new SpecialCollection<int, int, int>();

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 10000; i++)
            {
                cd.TryAdd(new CompositeKey<int, int>(i, i), i);
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

            sw.Start();
            for (int i = 0; i < 10000; i++)
            {
                sc.Add(new CompositeKey<int, int>(i, i), i);

            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
Run Code Online (Sandbox Code Playgroud)

谢谢!

Ben*_*son 5

我自己测试过,性能几乎没有差别.鉴于您的测试代码,性能差异可能是因为您没有在测试之间重置秒表.正如文件所说:

当秒表实例测量多个间隔时,Stop方法相当于暂停经过时间测量.随后对Start的调用将恢复从当前经过时间值开始测量时间.使用"重置"方法清除秒表实例中的累计已用时间.

所以只需sw.Reset()在测试之间添加一个.

在我的测试中,我确实设法通过使用lock关键字而不是a 来获得非常小的性能提升ReaderWriterLockSlim,尽管它可能是随机的.