|
First off please use the correct formatting when posting code snippets to make it easier to read. Use the "code" toolbar item above the textbox when entering your question/response.
If all you are doing is iterating through the string array to insert a separator you could use the String.Join[^] method
string withSeperators = String.Join("/r/n", sorted);
However, with very few items in the array the StringBuilder method should be faster than you have indicated.
No comment
|
|
|
|
|
Tried the join method. It actually took quite a bit longer than the builder one. I think the processing time has to do with the class I attached in the link in my 3rd post. Apparently the methods in that class are called upon when concatenating 'sorted' with "\r\n" (didn't even know that was possible to tell the truth).
Anyone know of a better natural sort, or am I maybe implementing it wrong?
Can I convert 'sorted' (ienumerator type) to a string[] somehow, and then append based on that copy?
If anyone can help demystify the best approach to a natural sort that would be great.
Appreciate all the help guys. I'm off to school, so I won't reply for some time most likely.
~Travis
|
|
|
|
|
|
Try changing your Func:
Func<string, object> convert = str =>
{
int value = 0;
return int.TryParse(str, out value) ? (object)value : str;
};
That could fix your problem.
|
|
|
|
|
Emardini,
Tried your code. Worked like a dream. That said, this part of the program was borrowed from the link above, so I never really understood it in the first place. I have gone from several minute sorts to < 1 second.
Func<string, object> convert = str =>
{
try { return int.Parse(str); }
catch { return str; }
};
Func<string, object> convert = str =>
{
int value = 0;
return int.TryParse(str, out value) ? (object)value : str;
};
Emardini, or anyone else. Can you break this down and explain what the difference/ meaning of both functions is? I know that sounds silly since it's from my program, but this project is merely to polish up on what I learned in previous semesters, complete a mundane task, and learn as much as possible along the way.
Edit:Having looked at this a bit more, if I understand right 'out' vs 'return' is the key difference. Still not entirely sure on what that means in the context of the above code.
modified 3-Dec-11 3:15am.
|
|
|
|
|
The simple fact is that "exception handling" (the "try...catch" block) is very "expensive" in terms of overhead; what with "stack unwinding", etc.
"try ... catch" blocks are for "exceptional" conditions; not for performing "data validation" (i.e. instead of "TryParse").
|
|
|
|
|
Great answer. Thanks a lot to everyone that replied to this thread. Really great info!! Learned a lot, and it works great too.
~Travis
|
|
|
|
|
Other minor points:
Try AppendFormat rather than two Appends.
And try pre-alloctaing the StringBuilder --
StringBuilder builder = new StringBuilder(txtOutput.Text.Length);
(before clearing the TextBox)
|
|
|
|
|
If "sorted" is as you say an array of strings, why faff with it at all?
txtOutput.Lines = sorted;
I just tried your code and mine:
string[] data = File.ReadAllLines(@"D:\Temp\MyLargeTextFile.txt");
Stopwatch s1 = new Stopwatch();
Stopwatch s2 = new Stopwatch();
s1.Start();
textBox1.Lines = data;
s1.Stop();
s2.Start();
StringBuilder sb = new StringBuilder();
foreach (string s in data)
{
sb.Append(s);
sb.Append("\r\n");
}
textBox2.Text = sb.ToString();
s2.Stop();
Console.WriteLine("{0} lines: {1}/{2}", data.Length,s1.Elapsed, s2.Elapsed);
The output I get is nothing like yours:
22777 lines: 00:00:01.5580246/00:00:01.5555734
How did you time your operations?
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
You're using two distinct stopwatches. When was the last time you had them calibrated?
|
|
|
|
|
I make sure to have my .NET stopwatches calibrated every time I re-wind them...
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Can you show where you put your timing code?
There is no reason why adding to a StringBuilder should take any noticeable amount of time. I wrote a simple test function in my toy language
x:
dt←$DateTime:Now;
sb←#new $StringBuilder ⍬;
{sb:AppendLine (⍵:ToString)}¨⍳x;
($DateTime:Now)-dt
... and it can add 10,000 lines in under a second. (Most of that is to do with pushing the function in my language onto the stack 10,000 times, I think.)
Your times look quadratic. Are you calling this function (sorted.Count) times?
|
|
|
|
|
You could always use the StrCmpLogicalW function that Windows Explorer uses to sort your items.
How to use in C#: StrCmpLogicalW
Use this in an IComparer like here.
Then your StringBuilder loop should run really fast.
|
|
|
|
|
You could combne the two lines:
builder.AppendFormat("{0}\r\n", s);
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|
|
builder.AppendLine(s); would do the trick also
No memory stick has been harmed during establishment of this signature.
|
|
|
|
|
Since you're using readonly single-line items, I'd suggest using a ListBox . You might want to temporarily disable painting when adding multiple items.
Bastard Programmer from Hell
|
|
|
|
|
What's missing in this scenario is information about where the strings you add newlines to are coming from.
If you are reading them in from a file, and they are delimited by newlines, that's one case: in that case you can add them to your StringBuilder as you read the file, a line at a time, taking care of delimiting with newlines right there. If it's a file, but not delimited with newlines, and you've got to parse the whole file to create the whatever semantic units that are to become "lines," that's another story. And, finally, if these strings are being created on-the-fly by you ... being calculated/composed in some way: another scenario.
If you can focus on getting the strings into a List<string>, you can just call 'Sort on that List, and then you can directly fill a TextBox by setting the 'Lines property of that TextBox (an array of string) to, courtesy of Linq, the List<string> converted to an array: as in:
List<string> sl = new List<string> { "wo", "ab", "c"};
sl.Sort();
textBox1.Lines = sl.ToArray(); And all of the above, as is said in almost every answer above, should not obscure that the problem here is probably not in the speed of StringBuilder itself.
"Anyone who shows me my 'blind spots' gives me the gift of sight." ... a thought from the shallows of the deeply shallow mind of ... Bill
|
|
|
|
|
Hi All !
There are some Items in my List Box(ListBox1) include "Positive" or "Negative" items ,so when I want to add Positive , "Fore color" for this Item in list Box should be Green , and if I want to add Negative item to List Box , "Fore color" for this Item in list Box should be Red :
if (ListBox1.Items.ToString() == "Positive")
ListBox1.ForeColor = Color.Green;
else
ListBox1.ForeColor = Color.Red;
thanks for any Help !
|
|
|
|
|
That's wrong cause you set the color for the entire listbox.
The best/easiest way is to set the DrawMode to OwnerDarwVariable and handle the ListBox.DrawItem event.
There you could use any brush you like to draw the text.
Just look for listboxDrawItem on bingle and you'll find lots of examples.
All the best,
Dan
|
|
|
|
|
Have you considered the ListView as an alternative to the ListBox. When set to the 'Details' view it supports per item colouring via the ListViewItem.ForeColor and .BackColor properties.
Alan.
|
|
|
|
|
All the best,
Dan
|
|
|
|
|
Wonde Tadesse
MCTS
|
|
|
|
|
Applying different ForeColors to the items of a ListBox is pretty easy; here[^] is an article that discusses an entirely different topic, however the download will show you how to get what you want.
|
|
|
|
|
You need to either custom draw the items or have a custom control (e.g. here is one by me[^]).
|
|
|
|
|
hello guys.. I have a function in some class (actually its DAL). Now return type of this function can be either DataTable, DataSet or DataRow like this
public DataTable function(int myTableKey)
{
DataTable dt;
return dt;
}
Now if everything goes right, this function returns me the data table.
But what if some goes wrong, like if I get some exception or I wanna return some string message in case of failure. What should I do? thnx
|
|
|
|