I have this simple for
loop with nothing inside. It takes almost 2 seconds to run, now, but if I replace the _img.width
with 512 then it runs almost in 0.001 milliseconds. What's the problem? Should I assign a local variable instead of using _img.width
? I'm wondering why it runs faster since it's just a number.
for (int aRowIndex = 0; aRowIndex < _img.width; aRowIndex += subsample)// For por cada fila de cada imagen
{
for (int aColumnIndex = 0; aColumnIndex < _img.height; aColumnIndex += subsample)//For por cada columna
{
}
}
why it runs faster since it's just a number
It is not just a number, it is a property. With a nontrivial implementation, unfortunately, there's an underlying unmanaged interop call involved that isn't very cheap. It blows up to an observable overhead due to the O(n^2) loop complexity.
You can simply solve it by caching the property value yourself:
int width = _img.Width;
int height = _img.Height;
for (int aRowIndex = 0; aRowIndex < width; aRowIndex += subsample)
{
for (int aColumnIndex = 0; aColumnIndex < height; aColumnIndex += subsample)
{
}
}
Looking at the .NET source for Image.Height
you can see that every type you get the property value it invokes an external call to gdiplus.dll
. It does not cache the value in .NET memory.
/// <summary>Gets the height, in pixels, of this <see cref="T:System.Drawing.Image" />.</summary>
/// <returns>The height, in pixels, of this <see cref="T:System.Drawing.Image" />.</returns>
public int Height
{
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
get
{
int result;
int num = SafeNativeMethods.Gdip.GdipGetImageHeight(new HandleRef(this, this.nativeImage), out result);
if (num != 0)
{
throw SafeNativeMethods.Gdip.StatusException(num);
}
return result;
}
}
By the way, this is actually against Microsoft's own guidelines: http://msdn.microsoft.com/en-us/library/vstudio/ms229054(v=vs.100).aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With