471,306 Members | 953 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,306 software developers and data experts.

Another question about performance

Hi,

Consider this:

ArrayList al = new ArrayList();
FillList(al);
/// NOW TWO SCENARIOS:

/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}

/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}
Yes, as you have already figured out my question is about preffered
scenario. I remember form the days of Delphi Pascal that you should
preffer second scenario as in the first property Count will be requested
on every loop.

Did anything change in C# and managed C++ or it's still proffered to use
scenario 2?

Thank you
MuZZy
Dec 23 '05 #1
15 1228
MuZZy <tn*@newsgroups.nospam> wrote:
Consider this:

ArrayList al = new ArrayList();
FillList(al);
/// NOW TWO SCENARIOS:

/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}

/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}
Yes, as you have already figured out my question is about preffered
scenario. I remember form the days of Delphi Pascal that you should
preffer second scenario as in the first property Count will be requested
on every loop.

Did anything change in C# and managed C++ or it's still proffered to use
scenario 2?


1) The property will almost certainly be inlined anyway
2) The performance difference even if there is one is very, very
unlikely to make any odds
3) The readability difference is much more significant, IMO
4) Do you actually need "i", or just the element? If it's the latter,
consider using foreach instead.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #2
MuZZy wrote:
Hi,

Consider this:

ArrayList al = new ArrayList();
FillList(al);
/// NOW TWO SCENARIOS:

/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}

/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}
Yes, as you have already figured out my question is about preffered
scenario. I remember form the days of Delphi Pascal that you should
preffer second scenario as in the first property Count will be requested
on every loop.

Did anything change in C# and managed C++ or it's still proffered to use
scenario 2?

Thank you
MuZZy

It has changed, it is scenario (1) when you use the indexer to access
the items in the ArrayList. By using al.Count there will be no runtime
check :-)
see http://tinyurl.com/3e9n3, part "Range Check Elimination"

Also, when you have an IEnumerable (which an ArrayList is) and the
IEnumerable is *not* an System.Array, this is as good:
foreach(OBJECT o in myList)
{
}
HTH,
Andy
--
To email me directly, please remove the *NO*SPAM* parts below:
*NO*SPAM*xmen40@*NO*SPAM*gmx.net
Dec 23 '05 #3
Jon Skeet [C# MVP] wrote:
MuZZy <tn*@newsgroups.nospam> wrote:
Consider this:

ArrayList al = new ArrayList();
FillList(al);
/// NOW TWO SCENARIOS:

/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}

/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}
Yes, as you have already figured out my question is about preffered
scenario. I remember form the days of Delphi Pascal that you should
preffer second scenario as in the first property Count will be requested
on every loop.

Did anything change in C# and managed C++ or it's still proffered to use
scenario 2?


1) The property will almost certainly be inlined anyway
2) The performance difference even if there is one is very, very
unlikely to make any odds
3) The readability difference is much more significant, IMO
4) Do you actually need "i", or just the element? If it's the latter,
consider using foreach instead.


Thanks for your reply Jon!

Let's imagine that i need 'i' inside the loop, or that it's C++ so i
can't use 'foreach'.
Now, how does compiler inline property if there is no guarantee that
it's not going to change inside the loop?

Dec 23 '05 #4
Andreas Mueller <me@privacy.net> wrote:

<snip>
It has changed, it is scenario (1) when you use the indexer to access
the items in the ArrayList. By using al.Count there will be no runtime
check :-)
see http://tinyurl.com/3e9n3, part "Range Check Elimination"


While I'm not saying it's a good idea to have a separate variable (see
my other posts), are you sure range check elimination applies to
ArrayLists as well as plain arrays? It doesn't explicitly say so in the
page you linked to.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #5
MuZZy <tn*@newsgroups.nospam> wrote:
Thanks for your reply Jon!

Let's imagine that i need 'i' inside the loop, or that it's C++ so i
can't use 'foreach'.
Now, how does compiler inline property if there is no guarantee that
it's not going to change inside the loop?


It inlines the property access so that there's no method call penalty -
it doesn't shift the property access to before the start of the loop.
It's the same as any other inlining.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #6
Hello Jon Skeet [C# MVP],

Whether don't using foreach give u slowing down?
AFAIK, msdn posted about don't use foreach if u'd like to gain performance.

J> MuZZy <tn*@newsgroups.nospam> wrote:
/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}
/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}

Did anything change in C# and managed C++ or it's still proffered to
use scenario 2?

J> 1) The property will almost certainly be inlined anyway
J> 2) The performance difference even if there is one is very, very
J> unlikely to make any odds
J> 3) The readability difference is much more significant, IMO
J> 4) Do you actually need "i", or just the element? If it's the latter,
J> consider using foreach instead.
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/members/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
Dec 23 '05 #7
Michael Nemtsev <ne*****@msn.com> wrote:
Hello Jon Skeet [C# MVP],

Whether don't using foreach give u slowing down?
Not significantly in my experience - and I'm not interested in
insignificant performance loss, pretty much by definition.
AFAIK, msdn posted about don't use foreach if u'd like to gain performance.


Well, that depends on which version of the framework you're using, and
what type you're using. However, I wouldn't worry about it until I'd
found it was decreasing the performance significantly, and that's never
happened to me yet.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #8
Hello Jon Skeet [C# MVP],

But it should be taken into account. In my work I regularly meet the conditions
when
for example delay for 2 secons brakes functional requirements.

Itetating for 1,000,000 recors with for in 3-4 times faster than foreach.

But I'm agree that it's depends on type of product.
Whether don't using foreach give u slowing down? J> Not significantly in my experience - and I'm not interested in
J> insignificant performance loss, pretty much by definition.
J> AFAIK, msdn posted about don't use foreach if u'd like to gain
performance.

J> Well, that depends on which version of the framework you're using,
J> and what type you're using. However, I wouldn't worry about it until
J> I'd found it was decreasing the performance significantly, and that's
J> never happened to me yet.
J>
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/members/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
Dec 23 '05 #9
Michael Nemtsev <ne*****@msn.com> wrote:
But it should be taken into account. In my work I regularly meet the conditions
when for example delay for 2 secons brakes functional requirements.
It would be a very rare situation where using a different form of
iteration would cost you even *nearly* that much. For instance, I can
iterate through a 1,000,000 record ArrayList using foreach *a hundred
times* in just over two seconds. Now, are you really doing that much
iteration in the space of time in which two seconds breaks functional
requirements?
Itetating for 1,000,000 recors with for in 3-4 times faster than foreach.


With what type? An ArrayList or an array? Big difference.

And what are you doing *inside* the loop? If you're not doing anything
significant, you should ask yourself how often you actually iterate
through a million records to do nothing with them. More often, in my
experience, you do something significant within the loop which makes
the actual iteration cost irrelevant.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 23 '05 #10
Hello Jon Skeet [C# MVP],

J> Michael Nemtsev <ne*****@msn.com> wrote:
J>
But it should be taken into account. In my work I regularly meet the
conditions when for example delay for 2 secons brakes functional
requirements.
J> It would be a very rare situation where using a different form of
J> iteration would cost you even *nearly* that much.

Indeed. Just a simple iterating 10,000,000 of int in int[] give u such
difference
with for and foreach

J> Now, are you really doing that much iteration in the space of time in
which two seconds breaks functional
J> requirements?

yep, but not just only using for :)
Itetating for 1,000,000 recors with for in 3-4 times faster than
foreach.

J> With what type? An ArrayList or an array? Big difference.

let's take just int[] (not talking abt datasets ;) ), performance in
that case differs in 2 times

J> And what are you doing *inside* the loop? If you're not doing
J> anything significant, you should ask yourself how often you actually
J> iterate through a million records to do nothing with them. More
J> often, in my experience, you do something significant within the loop
J> which makes the actual iteration cost irrelevant.

Agree, but using *for* instead *foreach* in code not so hard (when even
code navigation tools generate *for* template automatically) to win a bit
more performance, if u r even only iterating and perform some financial calculations.

Jon, I'm not trying to argue abt *foreach* is bad and *for* rocks, I just
wanna try to say, that using *for* is too simple .
It's not a panacea. But if u r developing back-end/server side app, using
*for* is more proper way
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/members/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
Dec 24 '05 #11
Jon Skeet [C# MVP] wrote:
Andreas Mueller <me@privacy.net> wrote:

<snip>
It has changed, it is scenario (1) when you use the indexer to access
the items in the ArrayList. By using al.Count there will be no runtime
check :-)
see http://tinyurl.com/3e9n3, part "Range Check Elimination"

While I'm not saying it's a good idea to have a separate variable (see
my other posts), are you sure range check elimination applies to
ArrayLists as well as plain arrays? It doesn't explicitly say so in the
page you linked to.

No, that was a mistake from my side. It does not apply to ArrayList,
just for System.Array.

Cheers,
Andy
--
To email me directly, please remove the *NO*SPAM* parts below:
*NO*SPAM*xmen40@*NO*SPAM*gmx.net
Dec 24 '05 #12
Michael Nemtsev <ne*****@msn.com> wrote:
Hello Jon Skeet [C# MVP],

J> Michael Nemtsev <ne*****@msn.com> wrote:
J>
But it should be taken into account. In my work I regularly meet the
conditions when for example delay for 2 secons brakes functional
requirements.
J> It would be a very rare situation where using a different form of
J> iteration would cost you even *nearly* that much.

Indeed. Just a simple iterating 10,000,000 of int in int[] give u such
difference
with for and foreach
Hmm. Not on my box - iterating through 10,000,000 ints using foreach
takes 0.03 seconds. Here's my test code:

using System;

class Test
{
public static void Main(String [] args)
{
int[] x = new int[10000000];

int total=0;

DateTime start = DateTime.Now;
foreach (int y in x)
{
total += y;
}
Console.WriteLine (DateTime.Now-start);
}
}

What does that print on your box?

Don't forget to run it outside a debugger.
J> Now, are you really doing that much iteration in the space of time in
which two seconds breaks functional
J> requirements?

yep, but not just only using for :)

Itetating for 1,000,000 recors with for in 3-4 times faster than
foreach.

J> With what type? An ArrayList or an array? Big difference.

let's take just int[] (not talking abt datasets ;) ), performance in
that case differs in 2 times


Not in my experiments. Here's another example:

using System;

class Test
{
public static void Main(String [] args)
{
int[] x = new int[10000000];

int total=0;

DateTime start = DateTime.Now;
for (int iteration = 0; iteration < 100; iteration++)
{
foreach (int y in x)
{
total += y;
}
}
Console.WriteLine (DateTime.Now-start);

start = DateTime.Now;
for (int iteration = 0; iteration < 100; iteration++)
{
for (int i=0; i < x.Length; i++)
{
total += x[i];
}
}
Console.WriteLine (DateTime.Now-start);
}
}

On my box, that prints:
00:00:02.1093750
00:00:02.0625000

In other words, not only can it do 100 times as many iterations as you
claim to do before even reaching 2 seconds, but the speed difference is
pretty insignificant. Now, the difference is more significant if you
comment out the addition, but I think it's reasonable to assume you
want to do *something* with the value inside the loop...

I don't understand how you're getting such different results, unless
you're running them in the debugger. Even in the debugger I'm not
seeing as much of a difference as you seem to be though.

What code did you use to test the difference?
J> And what are you doing *inside* the loop? If you're not doing
J> anything significant, you should ask yourself how often you actually
J> iterate through a million records to do nothing with them. More
J> often, in my experience, you do something significant within the loop
J> which makes the actual iteration cost irrelevant.

Agree, but using *for* instead *foreach* in code not so hard (when even
code navigation tools generate *for* template automatically) to win a bit
more performance, if u r even only iterating and perform some financial calculations.

Jon, I'm not trying to argue abt *foreach* is bad and *for* rocks, I just
wanna try to say, that using *for* is too simple .
It's not a panacea. But if u r developing back-end/server side app, using
*for* is more proper way


Only when you've found you've *actually* got a problem. It's easier to
make a mistake with for than it is with foreach, and if you use foreach
it's clear from reading the code that you're *only* interested in the
values, and not in their positions. In other words, the code is simpler
and conveys more correct information. *That* sounds like a the "more
proper" way unless you *know* that you actually gain something
significant from using a for loop.

Using the test code I've posted above, you'd have to be iterating
through an array of 10,000,000 ints 5000 times in order to get a two
second performance improvement. Now, unless you're actually doing very,
very little work inside the loop, chances are that going through that
much data is going to take so much time that 2 seconds becomes
irrelevant.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 24 '05 #13
Hello Jon Skeet [C# MVP],

Indeed. Just a simple iterating 10,000,000 of int in int[] give u
such
difference
with for and foreach J> Hmm. Not on my box - iterating through 10,000,000 ints using foreach
J> takes 0.03 seconds. Here's my test code:
J>
J> What does that print on your box?
J> Don't forget to run it outside a debugger.

The same result
J> Now, are you really doing that much iteration in the space of time
in
which two seconds breaks functional
J> requirements?
yep, but not just only using for :)
Itetating for 1,000,000 recors with for in 3-4 times faster than
foreach.

J> With what type? An ArrayList or an array? Big difference.

let's take just int[] (not talking abt datasets ;) ), performance in
that case differs in 2 times

J> Not in my experiments. Here's another example:
J> On my box, that prints:
J> 00:00:02.1093750
J> 00:00:02.0625000

The same too

J> What code did you use to test the difference?

on big loops with rich logic inside

J> Only when you've found you've *actually* got a problem. It's easier
J> to make a mistake with for than it is with foreach, and if you use
J> foreach it's clear from reading the code that you're *only*
J> interested in the values, and not in their positions. In other words,
J> the code is simpler and conveys more correct information. *That*
J> sounds like a the "more proper" way unless you *know* that you
J> actually gain something significant from using a for loop.

Can't but agree too, but it's individual choice

J> Using the test code I've posted above, you'd have to be iterating
J> through an array of 10,000,000 ints 5000 times in order to get a two
J> second performance improvement. Now, unless you're actually doing
J> very, very little work inside the loop, chances are that going
J> through that much data is going to take so much time that 2 seconds
J> becomes irrelevant.

My posts based on practical result, when I've seen the n-times improving
performance changing foreach to for in nested loops. And it wasn't ArrayList.

I totally agree that it's not important in must cases.

---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/members/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
Dec 24 '05 #14
Michael Nemtsev <ne*****@msn.com> wrote:

<snip>
J> What code did you use to test the difference?

on big loops with rich logic inside
And you saw a two second difference, using the same data, *just*
changing from a for loop to a foreach loop? I hope you can see why I'm
surprised, given the results we saw in my test code. The more complex
the logic in the loop is, the less significance there will be in the
iteration part.
J> Only when you've found you've *actually* got a problem. It's easier
J> to make a mistake with for than it is with foreach, and if you use
J> foreach it's clear from reading the code that you're *only*
J> interested in the values, and not in their positions. In other words,
J> the code is simpler and conveys more correct information. *That*
J> sounds like a the "more proper" way unless you *know* that you
J> actually gain something significant from using a for loop.

Can't but agree too, but it's individual choice
It's certainly an individual choice, but it should be an informed one.
I would say that your blanket advice of "But if u r developing back-
end/server side app, using *for* is more proper way" is mistaken, when
in *most* cases the performance improvement isn't significant, but in
*all* cases the foreach code is simpler and more readalbe.
J> Using the test code I've posted above, you'd have to be iterating
J> through an array of 10,000,000 ints 5000 times in order to get a two
J> second performance improvement. Now, unless you're actually doing
J> very, very little work inside the loop, chances are that going
J> through that much data is going to take so much time that 2 seconds
J> becomes irrelevant.

My posts based on practical result, when I've seen the n-times improving
performance changing foreach to for in nested loops. And it wasn't ArrayList.

I totally agree that it's not important in must cases.


I'd still be interested to hear more about the case you saw where it
made a really significant improvement. I've just changed the test code
to do more iterations over a smaller array. That shows a significant
difference, but only when you get to the stage where you're iterating
over a two element array. Even using a three element array doesn't show
the problem. (Using 2.0 and compiling with optimisation on, this
difference is reversed - array access at that stage takes longer than
foreach.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 24 '05 #15
Check out the excellent "Effective C#" by Bill Wagner - its written assuming
..NET 1.1 (no doubt there will be a 2.0 shortly)

Item 11 (page 71) explains why your loop2 below is, in fact, the *slowest*
way to write these loops in C# despite the fact it was the fastest way under
C++ (doing it in .NET, you break the JITters ability to remove range
checking for the loop).
He also clearly explains why foreach is almost *always* the fastest method
iterate over a collection.

Rob
"MuZZy" <tn*@newsgroups.nospam> wrote in message
news:eD**************@TK2MSFTNGP09.phx.gbl...
Hi,

Consider this:

ArrayList al = new ArrayList();
FillList(al);
/// NOW TWO SCENARIOS:

/// 1.
for (int i = 0 ; i < al.Count ; i++)
{..do whatever..}

/// 2.
int iCount = al.Count;
for (int i = 0 ; i < iCount ; i++)
{..do whatever..}
Yes, as you have already figured out my question is about preffered
scenario. I remember form the days of Delphi Pascal that you should
preffer second scenario as in the first property Count will be requested
on every loop.

Did anything change in C# and managed C++ or it's still proffered to use
scenario 2?

Thank you
MuZZy

Dec 27 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Robin Tucker | last post: by
7 posts views Thread by Gui Lloyd | last post: by
2 posts views Thread by C Williams | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.