|
WriteY is static because you are calling it from the Main method without creating an instance of the Program class in the Main method.
|
|
|
|
|
I'm loving the Linq stuff, it's very cool and flexible, but I don't want to use is for the sake of it.
I currently have a Generic List of DVD objects that have Name and ID properties.
I'm writing a simple method in the List to return the Name of the DVD given an ID and return an empty string if it's not found.
Before I was doing
public string GetName(int ID)
{
foreach (DVD thisDVD in this)
{
if (thisDVD.ID == ID)
{ return thisDVD.Name; }
}
return "";
}
which works fine, but after playing with Linq, I found myself writing
public string GetName(int ID)
{
var idQuery =
from dvd in this
where dvd.ID == ID
select dvd.Name;
foreach (string name in idQuery)
{ return name; }
return "";
}
which works fine too.
I was wondering which to use? I figured that the first one was better, as in the second Linq is iterating over the collection and then I have to iterate over the results. Surely only one trip over and breaking out if/when the required result is found is better? Is there something in the framework that makes Linq more efficient?
Dave
modified on Saturday, February 9, 2008 7:25 AM
|
|
|
|
|
|
LINQ is a bit slower due to the overhead of tons of method calls (there are lots of calls to MoveNext() and the closure). The current JIT is not able to optimize this, but it's possible to write an IL-level optimizer that inlines all LINQ method calls, then inlines the closure method calls and removes the closure objects, converting the fields representing captured variables back into local variables.
I've written a prototype optimizer that can remove the closure in code like this:
static List<int> someIntList = new List<int>();
static bool ExistsTest(int divisor)
{
return Exists(someIntList, i => i % divisor == 0);
}
static bool Exists(IEnumerable<int> input, Predicate<int> pred)
{
if (pred == null) {
throw new ArgumentNullException("pred");
}
foreach (int i in input) {
if (pred(i))
return true;
}
return false;
}</int></int></int></int>
What's missing until it gets useful is cross-assembly inlining and support for generic methods.
|
|
|
|
|
Thanks cosmo - that's been very helpful
Dave
|
|
|
|
|
DaveyM69,
Since your using a List<t> why not do:
return list[list.IndexOf(ID)];
And you could always add list.Containts(ID) before the above to check its in the list so you dont get an exception. It just seems simpler/quicker than iterating.
Regards,
Gareth.
|
|
|
|
|
I would write it this way:
public string GetName(int ID)
{
return
(from dvd in this
where dvd.ID == ID
select dvd.Name
).FirstOrDefault() ?? "";
}
If performance of GetName is an issue, neither a loop nor LINQ is efficient; you should use a Dictionary ID->dvd.
|
|
|
|
|
Daniel Grunwald wrote: FirstOrDefault()
I was just looking at the Element Operations on MSDN
I've tried various ways of coding it and Linq is definately slower in ALL situations (it is more 'elegant' though) by between 30 and 50%.
Performance isn't really an issue in this app but I didn't want to deliberately add overhead.
Thanks for all your help and suggestions everyone!
Dave
|
|
|
|
|
One of the reasons that you would use LINQ is that it allows you to write simpler code.
You query for the DVD could be a lot shorter.
public string GetName(int ID)
{
return this.Where(d => d.ID == id).Select(d => d.Name).FirstOrDefault() ?? String.Empty;
}
This is acually quite efficient, as the linq operator doesn't copy any data, but uses chained yield return methods to find the required subset of dvd's. So Link is actually just as efficient as your code would be, with the added advantage of a simple query language.
WM.
What about weapons of mass-construction?
"What? Its an Apple MacBook Pro. They are sexy!" - Paul Watson
My blog
|
|
|
|
|
I've just tested it on one million records searching for the id 999999 and it still performs about 30 to 50% slower than a foreach loop.
It seems that regardless of what you atually try to do with a Linq query it calls some sort of internal ToArray() method (so the result supports the IEnumerable interface I assume) and that's where the performance is lost.
For complex queries I think Linq has some huge advantages, but for simple ones it seems the old foreach is better.
Dave
|
|
|
|
|
Why not simpy:
public string GetName(int ID) {
DVD found = this.Find(d => d.ID == ID);
return found != null ? found.Name : string.Empty;
}
But, as Daniel said, if performance is an issue, you should use a dictionary instead of a list.
Experience is the sum of all the mistakes you have done.
|
|
|
|
|
The dictionary would be fine if a 'real world' class were actually as simple as the example. If matching multiple properties then it's not much use.
That code performs 10 to 20% quicker than a foreach! Cool, thankyou!
Dave
|
|
|
|
|
DaveyM69 wrote: f matching multiple properties then it's not much use.
Then just make a key that contains multiple properties. Make a class that implements IEqualityComparer and use that as comparer when you create the dictionary.
DaveyM69 wrote: That code performs 10 to 20% quicker than a foreach!
Hm... that's pretty strange, as all the Find method does is looping through the items and calling the delegate...
A dictionary would perform about 100000% faster...
Experience is the sum of all the mistakes you have done.
|
|
|
|
|
DaveyM69 wrote: If matching multiple properties then it's not much use.
Regarding that, I wrote an article about how to make a custom key for a dictionary:
Dictionary with a custom key[^]
Experience is the sum of all the mistakes you have done.
|
|
|
|
|
Hi,Please tel me how I can scan a document in c#.thanks.
Chamanara Shapoor
|
|
|
|
|
Member 2671314,
What do you mean by "scan a document"?
Regards,
Gareth.
|
|
|
|
|
I would assume you want to loop through the text of the entire document for single terms/phrases. Just use a for loop or while(!stream.endoffile).
Regards,
Thomas Stockwell
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Visit my homepage Oracle Studios[ ^]
|
|
|
|
|
Buy an OCR toolkit and hook it in, or look at writing a TWAIN class. There should be some samples floating around that you could work from.
|
|
|
|
|
Hi,
thanks.twain?where i can find this?
Chamanara Shapoor
|
|
|
|
|
I want to convert an RGB Image to YCrCb Image. when i get the values for Y,Cr and Cb for every pixel Using Its RGB Values... what am i supposed to do with these values to get The Resultant Image ?
(Jameel)
|
|
|
|
|
i want help,because my program is not working properly.If anyone can help me that would be a great help for me.The codings which I tried is given below.
How to print a pyramid?
/using System;
class pyr
{
static void Main(string[] args)
{
int j,k,m;
int n;
Console.WriteLine("No of lines:");
n = Convert.ToInt32(Console.ReadLine());
for (j = 0; j <= n; j++)
{
for (k = 1; k <= n- j; k++)
{
Console.WriteLine("*");
}
for (m = 1; m <= j; m++)
{
Console.WriteLine("*");
}
for (m = 1; m < j; m++)
{
Console.WriteLine("*");
}
}
}
}/
Thanks.
|
|
|
|
|
Why isn't it working properly?
Why do you want to print a pyramid?
Paul Marfleet
"No, his mind is not for rent
To any God or government"
Tom Sawyer - Rush
|
|
|
|
|
for example i want to print a pyramid like this.
*
***
*****
*******
But it is printing like this
*
*
*
*
*
|
|
|
|
|
Do you know about new line ? ( Like /n in C/C++). If yes then use it.
Regards.
|
|
|
|
|
WriteLine includes a linefeed. You probably want to use just Write
|
|
|
|