diff --git a/src/System.Collections/src/System/Collections/Generic/Queue.cs b/src/System.Collections/src/System/Collections/Generic/Queue.cs index 14b165dec2c5..5c3d2d18c2a5 100644 --- a/src/System.Collections/src/System/Collections/Generic/Queue.cs +++ b/src/System.Collections/src/System/Collections/Generic/Queue.cs @@ -33,7 +33,6 @@ public class Queue : IEnumerable, private int _version; private const int MinimumGrow = 4; - private const int GrowFactor = 200; // double each time // Creates a queue with room for capacity objects. The default initial // capacity and grow factor are used. @@ -183,15 +182,31 @@ void ICollection.CopyTo(Array array, int index) // Adds item to the tail of the queue. public void Enqueue(T item) { - if (_size == _array.Length) + int tail = _tail; + int size = _size; + T[] array = _array; + + if ((uint)size < (uint)array.Length && (uint)tail < (uint)array.Length) { - int newcapacity = (int)((long)_array.Length * (long)GrowFactor / 100); - if (newcapacity < _array.Length + MinimumGrow) - { - newcapacity = _array.Length + MinimumGrow; - } - SetCapacity(newcapacity); + array[tail] = item; + MoveNext(ref tail, array); + _tail = tail; + _size = size + 1; + _version++; } + else + { + EnqueueWithResize(item); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void EnqueueWithResize(T item) + { + int length = _array.Length; + int newCapacity = Math.Max(length * 2, length + MinimumGrow); + + SetCapacity(newCapacity); _array[_tail] = item; MoveNext(ref _tail); @@ -357,15 +372,16 @@ private void SetCapacity(int capacity) _tail = (_size == capacity) ? 0 : _size; _version++; } + private void MoveNext(ref int index) => MoveNext(ref index, _array); // Increments the index wrapping it if necessary. - private void MoveNext(ref int index) + private void MoveNext(ref int index, T[] array) { // It is tempting to use the remainder operator here but it is actually much slower // than a simple comparison and a rarely taken branch. // JIT produces better code than with ternary operator ?: int tmp = index + 1; - if (tmp == _array.Length) + if (tmp == array.Length) { tmp = 0; }