using foreach Vs for

  • Thread starter Thread starter Ofer B.
  • Start date Start date
O

Ofer B.

Hi all,
I have 2 examples, when to use "for" and when "foreach".
In "example 1" we are using a simple array and the foreach loop the is
faster than the for loop.
In "example 2" we are using ArrayList and the for loop is faster than the
foreach loop.

The "TestOptimize()" is faster than the "TestStandard()".

I don't understand the reason for the difference between the 2 examples...

if you understand, please explane

Thanks
Ofer

****************** Example 1 ****************
static byte m_byte;
static byte[] m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestOptimized()
{
for (int i=0; i < 1000; i++)
foreach(byte b in m_array)
m_byte = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestStandard()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 100000; i++)
m_byte = m_array;
}
**************** Example 2 *****************************
static object m_obj;
static ArrayList m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestStandard()
{
for (int i=0; i < 1000; i++)
foreach(object b in m_array)
m_obj = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestOptimized()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 10000; i++)
m_obj = m_array;
}
*************************************************
 
I think you'll find your answer in ildasm. In case of arrayList list
iterator has probably some overhead compared to indexed access.

Looking in the implementation of IEnumerable and get_Item for both classes
we see that:
For Array the IEnumerator implementation is managed code that dereferences
next array element by incrementing the position inside the array, which
happens to be a simple increment by one in case of 1-dim array. The get_Item
accessor is implemented via P/Invoke, which probably is more efficient in
multidimensional array but the overhead of PInvoke makes it slower than
Enumerator

For arrayList the implmentation of IEnumerator::MoveNext seems to be more
complex (some extra runtime checks) than get_Item and hence slower.
 
Thanks Alex.

I understand the difference between the simple array and the ArrayList.
but why is the foreach loop is faster than the for loop for the simple array
(Example 1)?
I thought that a for loop is always faster than foreach, or is it
because "m_byte = b;" is faster than "m_byte = m_array;"?

Ofer




Alex Feinman said:
I think you'll find your answer in ildasm. In case of arrayList list
iterator has probably some overhead compared to indexed access.

Looking in the implementation of IEnumerable and get_Item for both classes
we see that:
For Array the IEnumerator implementation is managed code that dereferences
next array element by incrementing the position inside the array, which
happens to be a simple increment by one in case of 1-dim array. The get_Item
accessor is implemented via P/Invoke, which probably is more efficient in
multidimensional array but the overhead of PInvoke makes it slower than
Enumerator

For arrayList the implmentation of IEnumerator::MoveNext seems to be more
complex (some extra runtime checks) than get_Item and hence slower.

--
Alex Feinman
---
Visit http://www.opennetcf.org
Ofer B. said:
Hi all,
I have 2 examples, when to use "for" and when "foreach".
In "example 1" we are using a simple array and the foreach loop the is
faster than the for loop.
In "example 2" we are using ArrayList and the for loop is faster than the
foreach loop.

The "TestOptimize()" is faster than the "TestStandard()".

I don't understand the reason for the difference between the 2 examples...

if you understand, please explane

Thanks
Ofer

****************** Example 1 ****************
static byte m_byte;
static byte[] m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestOptimized()
{
for (int i=0; i < 1000; i++)
foreach(byte b in m_array)
m_byte = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestStandard()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 100000; i++)
m_byte = m_array;
}
**************** Example 2 *****************************
static object m_obj;
static ArrayList m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestStandard()
{
for (int i=0; i < 1000; i++)
foreach(object b in m_array)
m_obj = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestOptimized()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 10000; i++)
m_obj = m_array;
}
*************************************************

 
It's not that foreach is faster. The for loop that uses indexer, which is
implemented via Item property, for which the accessor get_Item works via
PInvoke. It looks like PInvoke perf penalty is high enough to offset the
results

--
Alex Feinman
---
Visit http://www.opennetcf.org
Ofer B. said:
Thanks Alex.

I understand the difference between the simple array and the ArrayList.
but why is the foreach loop is faster than the for loop for the simple
array
(Example 1)?
I thought that a for loop is always faster than foreach, or is it
because "m_byte = b;" is faster than "m_byte = m_array;"?

Ofer




Alex Feinman said:
I think you'll find your answer in ildasm. In case of arrayList list
iterator has probably some overhead compared to indexed access.

Looking in the implementation of IEnumerable and get_Item for both
classes
we see that:
For Array the IEnumerator implementation is managed code that
dereferences
next array element by incrementing the position inside the array, which
happens to be a simple increment by one in case of 1-dim array. The get_Item
accessor is implemented via P/Invoke, which probably is more efficient in
multidimensional array but the overhead of PInvoke makes it slower than
Enumerator

For arrayList the implmentation of IEnumerator::MoveNext seems to be more
complex (some extra runtime checks) than get_Item and hence slower.

--
Alex Feinman
---
Visit http://www.opennetcf.org
Ofer B. said:
Hi all,
I have 2 examples, when to use "for" and when "foreach".
In "example 1" we are using a simple array and the foreach loop the is
faster than the for loop.
In "example 2" we are using ArrayList and the for loop is faster than the
foreach loop.

The "TestOptimize()" is faster than the "TestStandard()".

I don't understand the reason for the difference between the 2 examples...

if you understand, please explane

Thanks
Ofer

****************** Example 1 ****************
static byte m_byte;
static byte[] m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestOptimized()
{
for (int i=0; i < 1000; i++)
foreach(byte b in m_array)
m_byte = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestStandard()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 100000; i++)
m_byte = m_array;
}
**************** Example 2 *****************************
static object m_obj;
static ArrayList m_array;

/// <summary>
/// This method uses iterator to go through
/// the array's elements
/// </summary>
public static void TestStandard()
{
for (int i=0; i < 1000; i++)
foreach(object b in m_array)
m_obj = b;
}
/// <summary>
/// This method access the array's elements
/// thorugh index accessor
/// </summary>
public static void TestOptimized()
{
for (int s = 0; s < 1000; s++)
for(int i =0; i < 10000; i++)
m_obj = m_array;
}
*************************************************


 
Back
Top