473,321 Members | 1,916 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

What should I Use ?

Hi all,

Imagine I've an array of int :

int[] anArray = new int[..];

I want to extract all the integer that are superior to 500

I can do :

var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

or

var resultFind = Array.FindAll(anArray, elt =elt 500);

or

var resultWhere = anArray.Where(elt =elt 500);

or

var resultLinq = from i in anArray where i 500 select i;

What is the best way ?

Thanks for your answer
Jul 9 '08 #1
10 1688
ti*********@gmail.com wrote:
Imagine I've an array of int :

int[] anArray = new int[..];

I want to extract all the integer that are superior to 500

I can do :

var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

or

var resultFind = Array.FindAll(anArray, elt =elt 500);

or

var resultWhere = anArray.Where(elt =elt 500);

or

var resultLinq = from i in anArray where i 500 select i;

What is the best way ?
Methods #1 and #2 create new collections, #3 and #4 do not (in fact they do
not create anything; they will yield a new sequence only when evaluated).
Methods #3 and #4 use LINQ (and thus require .NET 3.5), methods #1 and #2 do
not. Readability is subjective, but #1 is obviously less direct than the
other three methods.

The answer is therefore predictably "it depends". In general, I'd pick
whichever one was most convenient in the context (do I need a List, an
Array, an IEnumerable?) and switch if profiling results or other
circumstances dictated otherwise. in isolation, it's too small a problem to
pick the "best way".

--
J.
Jul 9 '08 #2
My suggestion would be to write a small windows forms app that makes a LARGE
array of number like the one you have to search, then add 4 buttons and
behind each one, put the code to do one of the methods. Time the execution of
the search using a stopwatch and see how long each takes.
The stopwatch is supposed to be a high accuracy timer for doing things like
these.
Try to make the array large so the difference between the techniques are
exposed.

Post the results and let us know.

--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com
"ti*********@gmail.com" wrote:
Hi all,

Imagine I've an array of int :

int[] anArray = new int[..];

I want to extract all the integer that are superior to 500

I can do :

var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

or

var resultFind = Array.FindAll(anArray, elt =elt 500);

or

var resultWhere = anArray.Where(elt =elt 500);

or

var resultLinq = from i in anArray where i 500 select i;

What is the best way ?

Thanks for your answer
Jul 9 '08 #3
Ciaran O''Donnell <Ci************@discussions.microsoft.comwrote:
My suggestion would be to write a small windows forms app that makes a LARGE
array of number like the one you have to search, then add 4 buttons and
behind each one, put the code to do one of the methods. Time the execution of
the search using a stopwatch and see how long each takes.
The stopwatch is supposed to be a high accuracy timer for doing things like
these.
Try to make the array large so the difference between the techniques are
exposed.

Post the results and let us know.
Note that that suggests that "best" == "fastest". Personally I'd pick
the means which is the most readable. For me, that's:

anArrayWhere(elt =elt 500);

I'd only start worrying about performance when I had some evidence that
it was really significant.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 9 '08 #4
On Jul 9, 7:53*am, timor.su...@gmail.com wrote:
Hi all,

Imagine I've an array of int :

int[] anArray = new int[..];

I want to extract all the integer that are superior to 500

I can do :

* * var result = new List<int>();
* * foreach (int i in anArray)
* * * * if (i 500)
* * * * * * result.Add(i);

or

* * var resultFind = Array.FindAll(anArray, elt =elt 500);

or

* * var resultWhere = anArray.Where(elt =elt 500);

or

* * var resultLinq = from i in anArray where i 500 select i;

What is the best way ?

Thanks for your answer
What you understand with "BEST" , fastest , less memory use, more
readable, more portable?

Depending of that you should select one method or other.

If you have a small list no method will be too different I think.

the first could be used in 2.0 , if you use linq you are forced to use
3.5

also if the code will be seen for somebody else then the first option
is trivial even if you do not know C# you could understand what it
does. the others are different though, each need to know a little bit
about C# from 2.0 features to LINQ

Jul 9 '08 #5
I understand your point but I like to know which options perform best in
which situations as I think it is better to code with performance in mind. If
you dont, you risk getting to the end of a development and realises you have
to go back through it and find optimisations to overcome a performance issue.
Some people call it premature optimizing and say it wastes time. If you
already know certain things are faster or more memory efficient then its good
to use them. It stops you having to come back to it later and it also helps
people reading your code pick up good ways to do things.
But each to their own and I fully understand in this case for a small array,
it wont make a difference at all. But if I or someone reading my code got to
a similar situation in the future with a more complex problem, having done
the research at this point might for-arm us with the knowledge of which one
performs better.

--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com
"Jon Skeet [C# MVP]" wrote:
Ciaran O''Donnell <Ci************@discussions.microsoft.comwrote:
My suggestion would be to write a small windows forms app that makes a LARGE
array of number like the one you have to search, then add 4 buttons and
behind each one, put the code to do one of the methods. Time the execution of
the search using a stopwatch and see how long each takes.
The stopwatch is supposed to be a high accuracy timer for doing things like
these.
Try to make the array large so the difference between the techniques are
exposed.

Post the results and let us know.

Note that that suggests that "best" == "fastest". Personally I'd pick
the means which is the most readable. For me, that's:

anArrayWhere(elt =elt 500);

I'd only start worrying about performance when I had some evidence that
it was really significant.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 9 '08 #6
On Jul 9, 11:58*pm, Ciaran O''Donnell
<CiaranODonn...@discussions.microsoft.comwrote:
I understand your point but I like to know which options perform best in
which situations as I think it is better to code with performance in mind..
Eek. I think readability is far more important. Only a tiny proportion
of the implementation is likely to have a really significant impact on
performance, whereas *all* of the code benefits from being as readable
as possible.
If you dont, you risk getting to the end of a development and
realises you have to go back through it and find optimisations to
overcome a performance issue.
I'd say you need to be aware of *architectural* performance at all
times, but not small pieces of *implementation* performance. Using a
profiler later on will usually find any bottlenecks pretty quickly -
so you can target those bottlenecks and use a more efficient solution
instead of the most readable one for that particular area.
Some people call it premature optimizing and say it wastes time.
It's not the waste of time that I primarily object to, it's the
emphasis on performance over readability.
If you already know certain things are faster or more memory
efficient then its good to use them.
So long as you know the situation well enough to be able to predict
that, of course. See later for my analysis of this particular
performance dilemma.
It stops you having to come back to it later and it also helps
people reading your code pick up good ways to do things.
No, it helps people reading your code pick up *fast* ways of doing
things, which:
a) may not be the most readable ways of have the clearest design
b) may slow them down when reading the code - chances are they want to
understand what's going on with the code, not learn performance tricks
c) may well not apply in situations which appear to be similar
But each to their own and I fully understand in this case for a small array,
it wont make a difference at all. But if I or someone reading my code gotto
a similar situation in the future with a more complex problem, having done
the research at this point might for-arm us with the knowledge of which one
performs better.
As a similar "each to their own" I'll readily acknowledge that there
*are* situations where performance matters, and I'm more likely to go
out of my way to use an efficient solution over a readable one if I
know in advance that the code is going to be heavily used, and/or used
on a low-power device. (Library code is a separate issue, as you often
don't know what the callers will be doing.)

Also, there are some "gotchas" which are just worth knowing about to
start with: don't use exceptions for flow control, don't concatenate
strings in a loop where you can use StringBuilder to great effect,
etc. I'm all for being *aware* of performance characteristics,
particularly where the differences are between O(n) and O(n^2)
complexity, for instance. I just believe that readability is king.

Now, let's look at the 4 proposed pieces of code. We can ignore the
last one (using a query expression) immediately, as the previous one
(with the Where call) results in exactly the same code. So, we're down
to 3. Here they are, reproduced and labeled (somewhere arbitrarily)
for future reference:

Option 1: "Manual"
var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

(Eek about the lack of braces, by the way...)

Option 2: "FindAll"

var resultFind = Array.FindAll(anArray, elt =elt 500);

Option 3: "LINQ"

var resultWhere = anArray.Where(elt =elt 500);
The first thing to consider is whether or not a list is actually
required. If it's not, then both Manual and FindAll will be wasting
time and memory building the list. This will have low impact when
there aren't many items found, but if the array becomes very large and
almost all elements are over 500, a lot of time may be wasted copying
the internal list buffer. Using a LinkedList instead in Manual would
put the algorithm back to O(n) but with a higher constant factor -
creating a node for the list is more expensive in both time and memory
than just setting an element in a backing array. If there is a
reasonable idea beforehand how many elements will be over 500, the
list's initial size could be specified to help alleviate things - at
the cost of potentially wasting memory if the guess is significantly
higher than reality.

The next thing to consider is the cost of iterating over the array.
Using "foreach" on an array compiles to different code than using it
on another IEnumerable<T>. The compiler knows how to access array
elements in a an efficient way, without needing any method calls.
FindAll will likewise be able to iterate very quickly, as it knows the
backing store internally. Where operates on an arbitrary
IEnumerable<Twhich forces it to genererate an IEnuerator<Tand call
MoveNext() and the Current property, which can't be inlined as the JIT
won't know what implementations it wil be used with.

Next comes the comparison. In Manual this is "inline" and probably
about as efficient as you'll get. The other two both use delegates in
the same way. I'd expect this to be less efficient than the inline
test, as the delegate call can't really be inlined as far as I can
see. One thing to watch out for is that this version doesn't capture
any variables. If the limit weren't set to 500, but the value of a
local variable, that would involve a delegate being created in a
different class, with an instance variable accessed for the limit. I
don't know whether or not that would have any significant effect, but
it might.

Finally there's laziness. The Where call won't actually cost anything
(of any significance) immediately. The only cost will be when the
result is iterated over. If the iteration actually stops after the
first few elements for whatever reason, then both Manual and FindAll
have done a lot of work for no benefit, whereas Where won't have done
any more work than is necessary.

All of these considerations will contribute to the performance based
on the actual situation, including the intended use of the result.
Whichever option ends up being the fastest for the OP's case may well
not be the fastest in a different context. That's one of the dangers
of the approach of "look at some code, learn the fastest way of doing
things." So often the answer to a performance question is "it
depends."

Jon
Jul 10 '08 #7
Thanks for that response, its pretty impressive.
I totally agree with what your saying and I also think readability is
important, and I also agree about the "it depends" answer to performance.
However, I think you have taken my comments as being my life view and
guiding principles where it is more like something I like to keep in mind.
I wouldn't go out of my way to introduce complex and hard to follow code on
the off chance it saves a couple of milliseconds on the 1 time its executed.
But I think its important to keep in mind things like looking to see if you
can predetermine approximate sizes for array based lists or a stringbuilder.
Often you cant but sometimes you can.
In an app I wrote recently, i was throwing out a file full of string
representations of certain objects. I didnt know the exact size but I knew it
was normally under 1kb per object and didnt vary that much, so I decided to
initialise the stringbuilder with a length of myObjectColllection.Count*1024.
This would have caused me to use a little more memory than I needed but I
would only have to allocate it once which made it faster and didnt change the
readability much as a comment explained the logic.
So really I do agree with you in terms of readability, and that you need to
analyse each situation individualy to determine the best ways of doing
something. But in a simple cases like this where readability isnt such a big
issue (they arent that different) I think is would be worth testing this to
find out which implementation does better for speed of the search. I however
am interested in things like that.

I really appreciate to taking the time to respond though
--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com
"Jon Skeet [C# MVP]" wrote:
On Jul 9, 11:58 pm, Ciaran O''Donnell
<CiaranODonn...@discussions.microsoft.comwrote:
I understand your point but I like to know which options perform best in
which situations as I think it is better to code with performance in mind..

Eek. I think readability is far more important. Only a tiny proportion
of the implementation is likely to have a really significant impact on
performance, whereas *all* of the code benefits from being as readable
as possible.
If you dont, you risk getting to the end of a development and
realises you have to go back through it and find optimisations to
overcome a performance issue.

I'd say you need to be aware of *architectural* performance at all
times, but not small pieces of *implementation* performance. Using a
profiler later on will usually find any bottlenecks pretty quickly -
so you can target those bottlenecks and use a more efficient solution
instead of the most readable one for that particular area.
Some people call it premature optimizing and say it wastes time.

It's not the waste of time that I primarily object to, it's the
emphasis on performance over readability.
If you already know certain things are faster or more memory
efficient then its good to use them.

So long as you know the situation well enough to be able to predict
that, of course. See later for my analysis of this particular
performance dilemma.
It stops you having to come back to it later and it also helps
people reading your code pick up good ways to do things.

No, it helps people reading your code pick up *fast* ways of doing
things, which:
a) may not be the most readable ways of have the clearest design
b) may slow them down when reading the code - chances are they want to
understand what's going on with the code, not learn performance tricks
c) may well not apply in situations which appear to be similar
But each to their own and I fully understand in this case for a small array,
it wont make a difference at all. But if I or someone reading my code got to
a similar situation in the future with a more complex problem, having done
the research at this point might for-arm us with the knowledge of which one
performs better.

As a similar "each to their own" I'll readily acknowledge that there
*are* situations where performance matters, and I'm more likely to go
out of my way to use an efficient solution over a readable one if I
know in advance that the code is going to be heavily used, and/or used
on a low-power device. (Library code is a separate issue, as you often
don't know what the callers will be doing.)

Also, there are some "gotchas" which are just worth knowing about to
start with: don't use exceptions for flow control, don't concatenate
strings in a loop where you can use StringBuilder to great effect,
etc. I'm all for being *aware* of performance characteristics,
particularly where the differences are between O(n) and O(n^2)
complexity, for instance. I just believe that readability is king.

Now, let's look at the 4 proposed pieces of code. We can ignore the
last one (using a query expression) immediately, as the previous one
(with the Where call) results in exactly the same code. So, we're down
to 3. Here they are, reproduced and labeled (somewhere arbitrarily)
for future reference:

Option 1: "Manual"
var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

(Eek about the lack of braces, by the way...)

Option 2: "FindAll"

var resultFind = Array.FindAll(anArray, elt =elt 500);

Option 3: "LINQ"

var resultWhere = anArray.Where(elt =elt 500);
The first thing to consider is whether or not a list is actually
required. If it's not, then both Manual and FindAll will be wasting
time and memory building the list. This will have low impact when
there aren't many items found, but if the array becomes very large and
almost all elements are over 500, a lot of time may be wasted copying
the internal list buffer. Using a LinkedList instead in Manual would
put the algorithm back to O(n) but with a higher constant factor -
creating a node for the list is more expensive in both time and memory
than just setting an element in a backing array. If there is a
reasonable idea beforehand how many elements will be over 500, the
list's initial size could be specified to help alleviate things - at
the cost of potentially wasting memory if the guess is significantly
higher than reality.

The next thing to consider is the cost of iterating over the array.
Using "foreach" on an array compiles to different code than using it
on another IEnumerable<T>. The compiler knows how to access array
elements in a an efficient way, without needing any method calls.
FindAll will likewise be able to iterate very quickly, as it knows the
backing store internally. Where operates on an arbitrary
IEnumerable<Twhich forces it to genererate an IEnuerator<Tand call
MoveNext() and the Current property, which can't be inlined as the JIT
won't know what implementations it wil be used with.

Next comes the comparison. In Manual this is "inline" and probably
about as efficient as you'll get. The other two both use delegates in
the same way. I'd expect this to be less efficient than the inline
test, as the delegate call can't really be inlined as far as I can
see. One thing to watch out for is that this version doesn't capture
any variables. If the limit weren't set to 500, but the value of a
local variable, that would involve a delegate being created in a
different class, with an instance variable accessed for the limit. I
don't know whether or not that would have any significant effect, but
it might.

Finally there's laziness. The Where call won't actually cost anything
(of any significance) immediately. The only cost will be when the
result is iterated over. If the iteration actually stops after the
first few elements for whatever reason, then both Manual and FindAll
have done a lot of work for no benefit, whereas Where won't have done
any more work than is necessary.

All of these considerations will contribute to the performance based
on the actual situation, including the intended use of the result.
Whichever option ends up being the fastest for the OP's case may well
not be the fastest in a different context. That's one of the dangers
of the approach of "look at some code, learn the fastest way of doing
things." So often the answer to a performance question is "it
depends."

Jon
Jul 10 '08 #8
I wish if you have added the hashlist into the discussion, would be better
to understand how HASHLIST functions. and might have a chance to read the
explanations from great personalities like John Skeet, Ciaran O' Donnell..

better late than never, pals .. I recommend Hash List.. what do you guys
say?
<ti*********@gmail.comwrote in message
news:3e**********************************@k37g2000 hsf.googlegroups.com...
Hi all,

Imagine I've an array of int :

int[] anArray = new int[..];

I want to extract all the integer that are superior to 500

I can do :

var result = new List<int>();
foreach (int i in anArray)
if (i 500)
result.Add(i);

or

var resultFind = Array.FindAll(anArray, elt =elt 500);

or

var resultWhere = anArray.Where(elt =elt 500);

or

var resultLinq = from i in anArray where i 500 select i;

What is the best way ?

Thanks for your answer
Jul 10 '08 #9
On Jul 10, 1:20*pm, "Chakravarthy" <dskch...@msn.comwrote:
I wish if you have added the hashlist into the discussion, would be better
to understand how HASHLIST functions. and might have a chance to read the
explanations from great personalities like John Skeet, Ciaran O' Donnell...

better late than never, pals .. I recommend Hash List.. what do you guys
say?
I don't see what the value would be. Could you give some example code
to say what you mean, and why you think it would help?

Jon
Jul 10 '08 #10
Thanks Jon for your answer,
I didn't know much about lazyness. For sure, it's better if I don't
need to iterate throught all the list.

This is now much clearer ;-)

On 10 juil, 14:57, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Jul 10, 1:20 pm, "Chakravarthy" <dskch...@msn.comwrote:
I wish if you have added the hashlist into the discussion, would be better
to understand how HASHLIST functions. and might have a chance to read the
explanations from great personalities like John Skeet, Ciaran O' Donnell..
better late than never, pals .. I recommend Hash List.. what do you guys
say?

I don't see what the value would be. Could you give some example code
to say what you mean, and why you think it would help?

Jon
Jul 10 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: thecrow | last post by:
Alright, what the hell is going on here? In the following code, I expect the printed result to be: DEBUG: frank's last name is burns. Instead, what I get is: DEBUG: frank's last name is...
220
by: Brandon J. Van Every | last post by:
What's better about Ruby than Python? I'm sure there's something. What is it? This is not a troll. I'm language shopping and I want people's answers. I don't know beans about Ruby or have...
699
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
92
by: Reed L. O'Brien | last post by:
I see rotor was removed for 2.4 and the docs say use an AES module provided separately... Is there a standard module that works alike or an AES module that works alike but with better encryption?...
137
by: Philippe C. Martin | last post by:
I apologize in advance for launching this post but I might get enlightment somehow (PS: I am _very_ agnostic ;-). - 1) I do not consider my intelligence/education above average - 2) I am very...
12
by: Dario | last post by:
The following simple program behaves differently in Windows and Linux . #include <stdexcept> #include <iostream> #include <string> using namespace std; class LogicError : public logic_error {...
125
by: Sarah Tanembaum | last post by:
Beside its an opensource and supported by community, what's the fundamental differences between PostgreSQL and those high-price commercial database (and some are bloated such as Oracle) from...
47
by: Neal | last post by:
Patrick Griffiths weighs in on the CSS vs table layout debate in his blog entry "Tables my ass" - http://www.htmldog.com/ptg/archives/000049.php . A quite good article.
121
by: typingcat | last post by:
First of all, I'm an Asian and I need to input Japanese, Korean and so on. I've tried many PHP IDEs today, but almost non of them supported Unicode (UTF-8) file. I've found that the only Unicode...
8
by: Midnight Java Junkie | last post by:
Dear Colleagues: I feel that the dumbest questions are those that are never asked. I have been given the opportunity to get into .NET. Our organization has a subscription with Microsoft that...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.