|
After a Linq discussion here a couple of days ago I found that
foundCollection = this.FindAll(data => data.ID > 0);
or
foundItem = this.Find(data => data.ID == ID);
inside a generic list was faster then using foreach.
I now want to use a method of the single item's class (data.ToCustomListViewItem) and return List<CustomListViewItem>
Is this possible?
I can do it using a foreach but would rather use an expression like those above.
Working example using foreach
public List<CustomListViewItem> CustomListViewItems()
{
List<CustomListViewItem> ReturnList = new List<CustomListViewItem>();
foreach (DVD thisDVD in this)
{
if (thisDVD.ID > 0)
{
ReturnList.Add(thisDVD.ToCustomListViewItem());
}
}
return ReturnList;
}
Dave
|
|
|
|
|
First, the performance gains by using FindAll or Find instead of a foreach are probably minimal, and not worth rewriting swaths of code. That said, you should use LINQ to imrpove readability of code. Also, the declarative nature of LINQ opens the door for real optimizations like PLINQ[^].
To answer your question, couple ways you can do this:
var listViewItems = from movie in dvds
where movie.ID > 0
select movie.ToCustomListViewItem(); That uses LINQ extension methods and should work just fine.
Another way is to use methods on your List<T> object itself:
List<DVD> dvdsWithPositiveId = dvds.FindAll(movie => movie.ID > 0);
List<CustomListViewItem> listViewItems = dvdsWithPositiveId.ConvertAll(movie => movie.ToCustomListViewItem());
|
|
|
|
|
Thank you for your response. The ConvertAll method may be what I was looking for. I'll try it now!
I did some benchmark tests and Linq performed consistantly 30% slower than a foreach but the second method (is this 'lambada'?) performed 20% faster than a foreach loop. That was simply searching for one objects ID property within a collection of objects.
Dave
|
|
|
|
|
LINQ is using lambda expressions as well. A lambda is essentially just a function you pass into another function. Both examples I gave were using lambdas under the hood.
The reason the List<T> methods may be slightly faster is because they've tuned it to a specific implementation (which is an array under the hood). The LINQ stuff might work slower because it doesn't know about any specific implementation; all it knows about is that it's working on IEnumerable<T> , which means it have to use a foreach to iterate over it, which is fast, but perhaps not as fast as List<T> highly optimized implementation as you point out.
Another thing to keep in mind is that because LINQ is declarative, it opens up real big optimizations that can happen under the hood. For example, say you have a quad processor. Given the following code:
var listViewItems = from movie in dvds.AsParallel()
where movie.ID > 0
select movie.ToCustomListViewItem();
Your query will now run approximately 4 times as fast as your List<T>.FindAll call, thanks to multiple cores. And since we'll be seeing more and more cores in the future, the above query will keep running faster and faster the more cores become available, with no extra work on your part. (A MS guy recently said Intel supplied them with an experimental 32-core desktop processor. When the day comes that we're all running 32 core processors, the above code will run about 32x as fast as List<T>.FindAll .)
.....Now, in regards to optimizing your code....
30% sounds good, but it may not be that big in practice. For example, if a foreach over your DVD collection takes 10 milliseconds, and a List<T>.Findall takes only 7 milliseconds, that's a 30% difference, but that's an indistinguishable 3 milliseconds to the end user. Big woop. Unless that code is in a hot loop being called millions of times, it makes no difference whether you use foreach, LINQ, or some List<T> method call.
My advice is this: make your code readable before doing optimizations, and optimize only the stuff that really matters. In this case, List<T>.FindAll and List<T>.ConvertAll is only slightly less readable than the LINQ version, so do what you please. But bear in mind, these kind of micro-optimizations are more or less worthless -- it's much more important to write easily-readable code.
|
|
|
|
|
Points taken and all lessons learnt!
Thank you for taking the time to explain it thoroughly. I'll persevere with my LINQ (and now PLINQ) leaning
Dave
|
|
|
|
|
How do I add PLINQ? Google has turned up System.Concurrency.dll or the standard System.Threading. I can't find System.Concurrency.dll and even though the System.Threading namespace is available I can't find PLINQ anywhere and Object Browser says it can't find it or the AsParallel() method.
I'm using Vista running VS2008/.NET 3.5
Edit: Here[^], Parallel Extentions if anyone else is looking!
Dave
modified on Wednesday, February 13, 2008 6:44 PM
|
|
|
|
|
Looks like you found it. Keep in mind PLINQ is in CTP -- early preview release, it's by no means finished. It will probably be included in .NET 4. But if you're using LINQ today, it will be easy to move to PLINQ in the future.
|
|
|
|
|
Is their a way to sort of serialize the data of a WPF richtextbox to save the formatting of the text in the control so it can be sent to an Access Database? I am working in the .NET framework 3.0.
Any help would be much appreciated
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[ ^]
|
|
|
|
|
Use rtf property of richtextbox class to save all text and formatting in database. BTW, now there is WPF forum too
|
|
|
|
|
I forgot about that forum. I just realized it existed just this past weekend, I'll be sure to post this question their. As for the rtf property goes, the WPF richtextbox does not have an RTF property. It uses the new Document class in the System.Windows.Document namespace.
Thanks,
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[ ^]
|
|
|
|
|
Ops, my mistake. Here is an example that shows how to save/load/print richtextbox in wpf: Save,Load,Print[^]
There is no need to double-post your question.
|
|
|
|
|
Thanks,
I now have so the text is outputted to an Access 2003 database, but now the only thing that I need to know if their is away to databind the XAML or RTF from the Database to the RichTextBox. None of the properties that deal with the RichTextBox content are dependency properties that databinding can be used with.
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[ ^]
|
|
|
|
|
Hi1 i have to start two threads. first thread copy file of 1 GB from source to destination & another copy file of 20 MB from source to destination. both thread uses same method. i run only 2 thread at a time. whenever one thread completes ,i can strat another that uses the same method. how can i know which one is completed so that i can start another?
|
|
|
|
|
|
There's a number of possibilities, for example: Use the the thread's Join method or use an AutoResetEvent to signal between threads.
Standards are great! Everybody should have one!
|
|
|
|
|
there also is the "IsAlive" property of the thread's object
|
|
|
|
|
Here`s a short code snippet:
SNIPPET[^]
The main purpose of this application was to test how critical regions work. In my opinion the first loop (with 'i' as index) should be performed in whole, so the abc variable should have the value of 100000001. Why does it have 88430?
Thank you very much for help in advance
|
|
|
|
|
Where does it say the loop is performed as a whole, without any time slicing? MSDN only says:
Notifies a host that execution is about to enter a region of code in which the effects of a thread abort or unhandled exception might jeopardize other tasks in the application domain
Standards are great! Everybody should have one!
|
|
|
|
|
Well no it's normal - you abort the thread after all.
The CriticalRegion just tells the CLR that you app will have major problems if you run into an exception in this region!
Here is the explanation from MSDN:
Hosts of the common language runtime (CLR), such as Microsoft SQL Server 2005, can establish different policies for failures in critical and non-critical regions of code. A critical region is one in which the effects of a thread abort or an unhandled exception might not be limited to the current task. By contrast, an abort or failure in a non-critical region of code affects only the task in which the error occurs.
For example, consider a task that attempts to allocate memory while holding a lock. If the memory allocation fails, aborting the current task is not sufficient to ensure stability of the AppDomain, because there can be other tasks in the domain waiting for the same lock. If the current task is terminated, other tasks could be deadlocked.
When a failure occurs in a critical region, the host might decide to unload the entire AppDomain rather than take the risk of continuing execution in a potentially unstable state. To inform the host that your code is entering a critical region, call BeginCriticalRegion. Call EndCriticalRegion when execution returns to a non-critical region of code.
Using this method in code that runs under SQL Server 2005 requires the code to be run at the highest host protection level.
I guess you want a way to make this code run no matter if a abort is called rigth? - Well you can't sorry (you can handle the ThreadAbortedException but only to die gracefully)
|
|
|
|
|
Hmm... let mi ask this simple question - so what exactly critical regions do? They warn CLR. So what? What does it warning do?
modified on Wednesday, February 13, 2008 9:23 AM
|
|
|
|
|
Hey guyz
Im having a problem with a userControll im writing. Basicly its a label that changes color based on the "status" of it red, yello or green. and then i use that to disply errors and general info like "Enter User Details Here"
Now on some of the forms of my app the posible error messages is longer than the form itself for example "Database Connection No Longer Avalibal > Transaction Terminated". So when i got at work this morning i decided to make the labels text scroll past.
this is the code i have so far (its not my actual controll, its just a test project)
its a form with a label on it
public partial class Form1 : Form
{
char charTemp;
string tempMessage = "";
string message = "";
TimerCallback timeCB;
System.Threading.Timer timer;
public Form1()
{
InitializeComponent();
}
public void scrollText(object state)
{
message = label1.Text;
charTemp = message[0];
for (int i = 0; i < message.Length - 1; i++)
{
tempMessage += message[i + 1];
}
tempMessage += charTemp;
label1.Text = tempMessage;
tempMessage = "";
}
private void Form1_Shown(object sender, EventArgs e)
{
timeCB = new TimerCallback(scrollText);
timer = new System.Threading.Timer(timeCB, null, 0, 1000);
}
}
now the obvios error i get is "Cross-thread operation not valid". But there must be a way to update the labels text after the 2nd thread runs its method
any ideas on how i can get it working?
Thanx
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
|
|
|
|
|
|
hey
i just read thru that... i dont quite understand it tho?
Harvey Saayman - South Africa
Junior Developer
.Net, C#, SQL
think BIG and kick ASS
|
|
|
|
|
|
It boils down to this: Don't update controls from any thread other than the thread that created them. You're breaking this rule by creating a new thread (timer ) and then manipulating a control from that (label1.Text ). As suggested you can use Control.Invoke to fix the problem or, and that would be my suggestion, use a System.Windows.Forms.Timer instead, which fires the Tick on the main UI thread.
Standards are great! Everybody should have one!
|
|
|
|