how to increase speed of my execution - c#

i am creating project in c#.net. my execution process is very slow. i also found the reason for that.in one method i copied the values from one list to another.that list consists more 3000values for every row . how can i speed up this process.any body help me
for (int i = 0; i < rectTristrip.NofStrips; i++)
{
VertexList verList = new VertexList();
verList = rectTristrip.Strip[i];
GraphicsPath rectPath4 = verList.TristripToGraphicsPath();
for (int j = 0; j < rectPath4.PointCount; j++)
{
pointList.Add(rectPath4.PathPoints[j]);
}
}
This is the code slow up my procees.Rect tristirp consists lot of vertices each vertices has more 3000 values..

A profiler will tell you exactly how much time is spent on which lines and which are most important to optimize. Red-gate makes a very good one.
http://www.red-gate.com/products/ants_performance_profiler/index.htm

Like musicfreak already mentioned you should profile your code to get reliable result on what's going on. But some processes are just taking some time.
In some way you can't get rid of them, they must be done. The question is just: When they are neccessary? So maybe you can put them into some initialization phase or into another thread which will compute the results for you, while your GUI is accessible to your users.
In one of my applications i make a big query against a SQL Server. This task takes a while (built up connection, send query, wait for result, putting result into a data table, making some calculations on my own, presenting the results to the user). All of these steps are necessary and can't be make any faster. But they will be done in another thread while the user sees in the result window a 'Please wait' with a progress bar. In the meantime the user can already make some other settings in the UI (if he likes). So the UI is responsive and the user has no big problem to wait a few seconds.
So this is not a real answer, but maybe it gives you some ideas on how to solve your problem.

You can split the load into a couple of worker threads, say 3 threads each dealing with 1000 elements.
You can synchronize it with AutoResetEvent

Some suggestions, even though I think the bulk of the work is in TristripToGraphicsPath():
// Use rectTristrip.Strip.Length instead of NoOfStrips
// to let the JIT eliminate bounds checking
// .Count if it is a list instead of array
for (int i = 0; i < rectTristrip.Strip.Length; i++)
{
VertexList verList = rectTristrip.Strip[i]; // Removed 'new'
GraphicsPath rectPath4 = verList.TristripToGraphicsPath();
// Assuming pointList is infact a list, do this:
pointList.AddRange(rectPath4.PathPoints);
// Else do this:
// Use PathPoints.Length instead of PointCount
// to let the JIT eliminate bounds checking
for (int j = 0; j < rectPath4.PathPoints.Length; j++)
{
pointList.Add(rectPath4.PathPoints[j]);
}
}

And maybe verList = rectTristrip.Strip[i]; // Removed 'VertexList' to save some memory
Define variable VertexList verList above loop.

Related

Wait until task has completed within a loop before executing next line of code

I am using Visual C# 2013 to create a win-forms applications. I have a loop which takes up to a minute to complete due to a large calculation having to be carried out on many rows of data within a table, therefore whilst the user waits I display a 'loading...' form.
On this form I wish to display a count down of the number of rows, so the user can see how many rows of the data there are left to be calculated, however the label with this number on will not update as everything 'freezes' until the loop has finished.
System.Windows.Forms.Form f = System.Windows.Forms.Application.OpenForms["LoadingForm"];
int DataRowsRemaining = TotalRowCount;
for (int i=0; i<=TotalRowCount; i++)
{
//CALCULATION CODE
((LoadingForm)f).label1.Text = Convert.ToString(DataRowsRemaining--);
}
This code does not allow the label to update during the loop. Using, Application.DoEvents(); after the label does allow it to be updated but this also refreshes every other label on the form which significantly slows down the calculation, therefore I think I need to allow this one line of code to be carried out on a separate thread.
Due to my knowledge being limited on the subject, could anyone advise me whether the multi-threading technique would be the best way to solve this issue, and if so any advice on how I could code this as I have been struggling to understand online examples of multi-threading.
Thanks for your time, Aaron.
Simplest way would be
await Task.Run(() => { /* CALCULATION CODE */ });
private async void Calculation()
{
for (int i = 0; i <= TotalRowCount; i++)
{
await Task.Run(() => { /* CALCULATION CODE */ });
((LoadingForm)f).label1.Text = Convert.ToString(DataRowsRemaining--);
}
}
There is an example here in MSDN on how to use .Invoke(). However, L.B's answer is probably much simpler.

C# Fastest way to find the index of item in a list

I want to know what is the fastest way to find the index of an item in a list. The reason I want to know is because I am making a XNA render but I started getting out of memory exceptions on larger models when I only used a vertex buffer, so I have now implemented an index buffer system. My problem is that I now have to continuously scan a list containing all my Vector3s for the index of the one that I want placed next in my index buffer. I am currently scanning for indices like this:
for (int i = 1; i < circleVect.Length; i++)
{
indices.Add(vertices.FindIndex(v3 => v3 == circleVect[i]));
indices.Add(vertices.FindIndex(v3 => v3 == circleVect[i - 1]));
indices.Add(vertices.FindIndex(v3 => v3 == middle));
}
This works fine except for the fact that it is rather slow. It takes almost 1 second for one cylinder to be calculated and I have more than 70 000 of them in my large model. I have therefore been seeing a loading screen for more than 20 minutes while loading my larger model and it still is not completed. This is unfortunately simply unacceptable. If I try loading my smaller model it takes more than 5 minutes whereas the unindexed loader took merely a second or so.
I have absolutely no formal training in C# and even less in XNA so I know this is probably a very inefficient way of calculating the indices so I would therefore appreciate it if any of you could assist me in creating a more efficient importer.
PS. If necessary I can change the list to an array but this would be a last resort option because it could potentially put strain on the system memory (causing an exception) and would mean quite a bit of coding for me.
in your code you are looping through your vertices 3 times one for each FindIndex line. Instead use one for loop and traverse and check for all three conditions in 1 go.
Your main performance killer is searching in a List of 70 000 items which takes 70 000 operations.
This will work a lot faster than searching in a list.
Dictionary<int, Vertice> vertices = new Dictionary<int, Vertice>();
for (int i = 1; i < vertices.Length; i++)
{
if (vertices.ContainsKey(vertices[i]))
{
indices.Add(vertices[i]);
}
if (vertices.ContainsKey(vertices[i - 1]))
{
indices.Add(vertices[i - 1]);
}
if (vertices.ContainsKey(vertices[middle]))
{
indices.Add(vertices[middle]);
}
}
edit: if searching in the list takes 2 seconds, searching in a dictionary will take 00:00:02 seconds
for (int i = 1; i < circleVect.Length; i++)
{
for (int j = 0; j < vertices.Count; j++)
{
var v3 = vertices[j];
if (v3 == circleVect[i] || v3 == circleVect[i - 1] || v3 == middle)
indices.Add(j);
}
}
You may want to consider adding logic to stop the inner loop from checking after all three of the indexes have been found.
Thanks for all the answers but none of them really worked and really appeard to be faster than what I had. I ended up having to create a structure where I could calculate the needed list index based on a given reference point.

Parallel.For loop freezes

I'm trying to add to a DataTable some information in Parallel but if the the loop is to long it freezes or just takes a lot of time, more time then an usual for loop, this is my code for the Parallel.For loop:
Parallel.For(1, linii.Length, index =>
{
DataRow drRow = dtResult.NewRow();
alResult = CSVParser(linii[index], txtDelimiter, txtQualifier);
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
);
What's wrong? this Parallel.For loop takes much more time than a normal one, what is wrong?
Thanks!
You can't mutate a DataTable from 2 different threads; it will error. DataTable makes no attempt to be thread-safe. So: don't do that. Just do this from one thread. Most likely you are limited by IO, so you should just do it on a single thread as a stream. It looks like you're processing text data. You seem to have a string[] for lines, perhaps File.ReadAllLines() ? Well, that is very bad here:
it forces it all to load into memory
you have to wait for it all to load into memory
CSV is a multi-line format; it is not guaranteed that 1 line == 1 row
What you should do is use something like the CsvReader from code project, but even if you want to just use one line at a time, use a StreamReader:
using(var file = File.OpenText(path)) {
string line;
while((line = file.ReadLine()) != null) {
// process this line
alResult = CSVParser(line, txtDelimiter, txtQualifier);
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
}
This will not be faster using Parallel, so I have not attempted to do so. IO is your bottleneck here. Locking would be an option, but it isn't going to help you massively.
As an unrelated aside, I notice that alResult is not declared inside the loop. That means that in your original code alResult is a captured variable that is shared between all the loop iterations - which means you are already overwriting each row horribly.
Edit: illustration of why Parallel is not relevant for reading 1,000,000 lines from a file:
Approach 1: use ReadAllLines to load the lines, then use Parallel to process them; this costs [fixed time] for the physical file IO, and then we parallelise. The CPU work is minimal, and we've basically spent [fixed time]. However, we've added a lot of threading overhead and memory overhead, and we couldn't even start until all the file was loaded.
Approach 2: use a streaming API; read each one line by line - processing each line and adding it. The cost here is basically again: [fixed time] for the actual IO bandwidth to load the file. But; we now have no threading overhead, no sync conflicts, no huge memory to allocate, and we start filling the table right away.
Approach 3: If you really wanted, a third approach would be a reader/writer queue, with one dedicated thread processing file IO and enqueueing the lines, and a second that does the DataTable. Frankly, it is a lot more moving parts, and the second thread will spend 95% of its time waiting for data from the file; stick to Approach 2!
Parallel.For(1, linii.Length, index =>
{
alResult = CSVParser(linii[index], txtDelimiter, txtQualifier);
lock (dtResult)
{
DataRow drRow = dtResult.NewRow();
for (int i = 0; i < alResult.Count; i++)
{
drRow[i] = alResult[i];
}
dtResult.Rows.Add(drRow);
}
});

c# update listbox without 'lag'

I've been searching the web for a way to do this without much success, so here's the question.
How do add items to a listbox in a separate thread, so that it doesn't freeze up the ui?
There are roughly 5-15k items each time added to the listboxes, and it freezes the ui for 5-12 seconds each time.
The form has 4 listboxes, the information for these listboxes is first created, and added to a 2D array (doing it this way makes it easier to keep track of all information that belongs together in 1 row). after which i loop over that 2D array, adding the 4 columns in 1 row to it's respective listbox.
eg.
for (int n = 0; n < 7500; n++)
{
listBox1.Items.Add(itemList[n, 0].ToString());
listBox2.Items.Add(itemList[n, 1].ToString());
listBox3.Items.Add(itemList[n, 2].ToString());
listBox4.Items.Add(itemList[n, 3].ToString());
}
As stated before, how to use a thread other than the UI to update these listboxes to prevent unnecessary freezing of the ui
You can take a different approach and use a virtual ListView instead. When a ListView is "virtual", you are responsible for maintaining item lists and telling ListView what to display on paint events. This way you can update your lists in any thread-safe way you'd like and ListView will only ask of you "what to draw on screen" rather than a full list of items. That's actually the preferred method when obtaining list of all items is very costly.
See the documentation on VirtualMode:
http://msdn.microsoft.com/en-us/library/system.windows.forms.listview.virtualmode.aspx
UPDATE: Since you mentioned that you need it for debugging I also suggest you to use debug output (Debug.WriteLine()) which could be more suitable for the job. It's optimized, it's thread safe, it doesn't block anything but itself and the best part is it doesn't affect performance of release builds.
And in case you need a more performant output you can redirect your debugging output to anywhere you like.
Use BeginUpdate() and EndUpdate()
http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.beginupdate.aspx
That's inherently impossible.
You can only manipulate the UI from the UI thread. (UI is not thread-safe)
You can make it faster by calling BeginUpdate() and EndUpdate(), and you can make it even faster (but harder) by using a ListView in virtual mode.
However, you should not display 15,000 items in a lsitbox.
Such a listbox would be useless in actual use.
listBox1.BeginUpdate();
listBox2.BeginUpdate();
listBox3.BeginUpdate();
listBox4.BeginUpdate();
for (int n = 0; n < 7500; n++)
{
listBox1.Items.Add(itemList[n, 0].ToString());
listBox2.Items.Add(itemList[n, 1].ToString());
listBox3.Items.Add(itemList[n, 2].ToString());
listBox4.Items.Add(itemList[n, 3].ToString());
}
listBox1.EndUpdate();
listBox2.EndUpdate();
listBox3.EndUpdate();
listBox4.EndUpdate();
This will delay drawing until all items have been added, so it should be faster.
You should try to use BeginUpdate/EndUpdate methods:
listbox1.BeginUpdate();
// Adds 5K items
listbox1.EndUpdate();
You can significantly speed up this process by preventing the ListBox from repainting after every add by wrapping the for loop in:
listBox1.BeginUpdate();
listBox2.BeginUpdate();
listBox3.BeginUpdate();
listBox4.BeginUpdate();
for (int n = 0; n < 7500; n++)
{
listBox1.Items.Add(itemList[n, 0].ToString());
listBox2.Items.Add(itemList[n, 1].ToString());
listBox3.Items.Add(itemList[n, 2].ToString());
listBox4.Items.Add(itemList[n, 3].ToString());
}
listBox1.EndUpdate();
listBox2.EndUpdate();
listBox3.EndUpdate();
listBox4.EndUpdate();
I just want to bring everyones answers together. You should really be updating items in your GUI thread or you may get unexpected results. To guarantee that the code is operating in the GUI thread and your list isn't repainting itself every Add() you need the BeingUpdate() and EndUpdate() pair, as others have posted, but to run that in the GUI thread use the BeingInvoke(), which simply puts the task on the "GUI thread queue" ready for consumption. BeingInvoke() will return immediate but your request will be put on the queue.
BeingInvoke() API Doc.
http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx
A good discussion on BeginInvoke() and why it is used.
BeginInvoke((MethodInvoker)delegate
{
listBox1.BeginUpdate();
listBox2.BeginUpdate();
listBox3.BeginUpdate();
listBox4.BeginUpdate();
for (int n = 0; n < 7500; n++)
{
listBox1.Items.Add(itemList[n, 0].ToString());
listBox2.Items.Add(itemList[n, 1].ToString());
listBox3.Items.Add(itemList[n, 2].ToString());
listBox4.Items.Add(itemList[n, 3].ToString());
}
listBox1.EndUpdate();
listBox2.EndUpdate();
listBox3.EndUpdate();
listBox4.EndUpdate();
});

Threadpools - possible thread execution order problem

I've been learning how to use the threadpools but I'm not sure that each of the threads in the pool are being executed properly and I suspect some are being executed more than once. I've cut down the code to the bare minimum and having been using Debug.WriteLine to try and work out what is going on but this produces some odd results.
My code is as follows (based on code from (WaitAll for multiple handles on a STA thread is not supported):
public void ThreadCheck()
{
string[] files;
classImport Import;
CountdownEvent done = new CountdownEvent(1);
ManualResetEvent[] doneEvents = new ManualResetEvent[10];
try
{
files = Directory.GetFiles(importDirectory, "*.ZIP");
for (int j = 0; j < doneEvents.Length; j++)
{
done.AddCount();
Import = new classImport(j, files[j], workingDirectory + #"\" + j.ToString(), doneEvents[j]);
ThreadPool.QueueUserWorkItem(
(state) =>
{
try
{
Import.ThreadPoolCallBack(state);
Debug.WriteLine("Thread " + j.ToString() + " started");
}
finally
{
done.Signal();
}
}, j);
}
done.Signal();
done.Wait();
}
catch (Exception ex)
{
Debug.WriteLine("Error in ThreadCheck():\n" + ex.ToString());
}
}
The classImport.ThreadPoolCallBack doesn't actually do anything at the minute.
If I step through the code manually I get:
Thread 1 started
Thread 2 started
.... all the way to ....
Thread 10 started
However, if I run it manually the Output window is filled with "Thread 10 started"
My question is: is there something wrong with my code for use of the threadpool or is the Debug.WriteLine's results being confused by the multiple threads?
The problem is that you're using the loop variable (j) within a lambda expression.
The details of why this is a problem are quite longwinded - see Eric Lippert's blog post for details (also read part 2).
Fortunately the fix is simple: just create a new local variable inside the loop and use that within the lambda expression:
for (int j = 0; j < doneEvents.Length; j++)
{
int localCopyOfJ = j;
... use localCopyOfJ within the lambda ...
}
For the rest of the loop body it's fine to use just j - it's only when it's captured by a lambda expression or anonymous method that it becomes a problem.
This is a common issue which trips up a lot of people - the C# team have considered changes to the behaviour for the foreach loop (where it really looks like you're already declaring a separate variable on each iteration), but it would cause interesting compatibility issues. (You could write C# 5 code which works fine, and with C# 4 it might compile fine but really be broken, for example.)
Essentially the local variable j you've got there is captured by the lambda expression, resulting in the old modified closure problem. You'll have to read that post to get a broad understanding of the issue, but I can speak about some specifics in this context.
It might appear as though each thread-pool task is seeing it's own "version" of j, but it isn't. In other words, subsequent mutations to j after a task has been created is visible to the task.
When you step through your code slowly, the thread-pool executes each task before the variable has an opportunity to change, which is why you get the expected result (one value for the variable is effectively "associated" with one task). In production, this isn't the case. It appears that for your specific test run, the loop completed before any of the tasks had an opportunity to run. This is why all of the tasks happened to see the same "last" value for j (Given the time it takes to schedule a job on the thread-pool, I would imagine this output to be typical.) But this isn't guaranteed by any means; you could see pretty much any output, depending on the particular timing characteristics of the environment you're running this code on.
Fortunately, the fix is simple:
for (int j = 0; j < doneEvents.Length; j++)
{
int jCopy = j;
// work with jCopy instead of j
Now, each task will "own" a particular value of the loop-variable.
the problem is that the j is a captured variable and is therefore the same capture reference is being used for each lambda expression.

Categories