Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange Queue<T>.Enqueue(T item) code

Tags:

c#

.net

While reflecting with ILSpy i found this line of code in the Queue<T>.Enqueue(T item)-method:

if (this._size == this._array.Length)
{
    int num = (int)((long)this._array.Length * 200L / 100L);
    if (num < this._array.Length + 4)
    {
        num = this._array.Length + 4;
    }
    this.SetCapacity(num);
}

I'm just wondering why somebody would do this? I think it's some kind of a integer overflow check, but why multiply first with 200L and then divide by 100L?

Might this have been a issue with earlier compilers?

like image 316
Felix K. Avatar asked Mar 23 '12 10:03

Felix K.


2 Answers

Usually things first multiplied then divided by 100 are percentage calculations - Perhaps there was some const XxxPercentage = 200 or something like that in the original code. The compiler does not seem to optimize the * 200 / 100 to * 2.

This code sets the capacity to twice its size - but if twice its size would be smaller than the original size + 4, use that instead.

The reason it is converted to long probably is because if you multiply an integer by the "200 percent" it would overflow.

like image 106
C.Evenhuis Avatar answered Sep 17 '22 21:09

C.Evenhuis


Below are all the same and will generate the same result:

int size = (int)((length * 200L) / 100L);
int size = length << 1;
int size = length * 2;

The reason for choosing the first option over the other is to show your intend clearly:

const long TotalArraySize = 200L;
const long BytesPerElement = 100L;
return (length * TotalArraySize) / BytesPerElement;

Some details about performance implications are given here: Doubling a number - shift left vs. multiplication

like image 29
Teoman Soygul Avatar answered Sep 17 '22 21:09

Teoman Soygul