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