I have a string with the format 00-00 and I want to increment it to 00-01.
Currently I am using Split() but I have the feeling that my approach is not really best practice.
I don't have to worry about edge cases and just want to know if there is an elegant solution.
Thanks
Linq approach without edge cases like 00-99 or 99-99
string input ="07-01";
string result = string.Join("-", input.Split('-')
.Select(int.Parse)
.Select((x, i) => (i == 1 ? ++x : x).ToString("00")));
Your method of utilizing string.Split() would be my suggestion too.
However, I'm wondering if you are repeatedly incrementing that number. if this is a one time action, then I agree with using the split method.
If you are continually incrementing this number (e.g. as a counter), you will start noticing that it takes more resources to do string operations (split) and conversions (string to int, int to string); compared to incrementing the value of the integer.
In this case, I would advocate that you keep the integer value in memory, and keep using that to generate your output string, instead of always having to start from scratch.
However, the latter suggestion only applies if you keep incrementing the same values. Your question did not specify that that is the case.
Related
I have recently began to start learning C# and try to write a program that's similar to a calculator in a console. I've already done it with two integers and it worked. Now I am trying to write the code allowing more user inputs to calculate with.
The thing is, that I have stuck at spliting the string from the user-input. So let's say for example he writes:
1 + 2 * 3 - 5 I want to split it where the space happens. It should still be splitting when the user uses more than just one spaces in between. It's like the same as 1,2,,3,,,,5,6,,,4 : How can you split by the comma when there are MORE than one comma used? I only want the integers (and the operators from example 1).
I have already tried with [string_name].Split(' ') and [string_name].Split(',') but it only seems to ignore ONE char variable between the user-input-values I am interested in. That makes it impossible for me to put the values in an array and convert them to int.
Last question regarding my first example (1 + 2 * 3 - 5):
Besides accepting multiple spaces/comma, how can you split this string input efficiently, keeping int inputs and the operators? My idea was to save every uneven input value (1, 2, 3, 5) and every even input value (+, *, -,/) in an array each. I considered to put the operators into a switch with 4 cases and convert the string_array with numbers to integers. After that I would have put them all together into the exact same order like the user-input using for.
The thing is: Assuming I implement it correctly, I think that the calculation would be solved from left to right without considering the precedence of '*' and '/'.
Someone an idea how you can solve this problem with the "advanced" calculator efficiently? I have thought for a long time and tried all I could, but it doesn't seem to work ... Makes me sad a bit. I'd really like to solve this problem somehow.
Well the answer to your first question, you can pass an overload to Split that will ignore empty entries:
str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
So more traditionally, you'd want to parse the string entirely so you could handle things like parenthesis and the case where there is no space: 4*(1+2) for instance.
I am try to control multiple strings variables is empty or not at once:
My first approach is very simple:
if(string.isNullOrEmpty(val1) && string.isNullOrEmpty(val2) && string.isNullOrEmpty(val3))
My second way looks like this
if(string.isNullOrEmpty(val1 + val2 + val3))
Which one is fastest and elegant?
Is there any options to do this operation?
The first was faster in my test (just had to): 6ms vs. 70ms and that was on 10,000,000 iterations each (so the speed difference probably doesn't matter very much unless you're doing this on a massive scale).
Anyway, i find the first to be more clear.
Also it doesn't rely on behavior of IsNullOrEmpty that is not immediately obvious (you might just as well think that passing null parameters causes an ArgumentNullException if you don't know better), which i think is important.
Note: The test was with all variables set to null, but setting them to other values confirms it, the longer the strings get, the longer option 2 takes, while option 1 stays at about 30ms max.
Also, the first returns true if any of the strings is null or empty, while the second does it only if all of them are null or empty. So it's not the same check.
They are not equivalent. The first one checks if any of them is null. The second one checks if all of them are null. Make up your mind.
How about this?
new string[] {val1, val2, val2}.All(s => string.IsNullOrEmpty(s))
Or something similar.
I would expect 'fastest' to depend on how often you expect one or more of the strings to actually be null or empty.
For example, if val1 is often going to be null or empty then the first option is likely to be best; if they are all rarely going to be null or empty then I'm not sure of the answer, but it can't take more than five minutes to knock together a few benchmarks for your particular expectations.
(Also, note that the two options don't do the same thing, the first is true if ANY of them are null or empty the second is not doing that)
if(string.isNullOrEmpty(val1 + val2 + val3)) seems to me the fastest
I would advice you to also use concat
but behind the scenes it uses the '+' operator.
I think this is the fastest.
If it werent nullable I suggest summing their length and check ==0
The second one:
if(string.isNullOrEmpty(val1 + val2 + val3))
equals
if(string.isNullOrEmpty(val1) && string.isNullOrEmpty(val2) && string.isNullOrEmpty(val3))
(note the && instead of ||)
but will create an intermediate string, whereas my second version will not create extra strings and stop checking as soon as one string is not empty.
If you have a number of string variables, then I think it is more readable to use the first construction:
if(string.isNullOrEmpty(val1) &&
string.isNullOrEmpty(val2) &&
string.isNullOrEmpty(val3))
{
}
This way, it seems like each variable is treated separately, and this code is a little easier to change if you need to treat one of the variables in another way.
But in case all of the string variables are to be treated in the same way, they are very likely to be represented as an array or another kind of enumeration. Then it's definitely better to use John M Gant's suggestion:
if(myStrings.All(s => string.IsNullOrEmpty(s)))
{
}
I have to read a huge xml file which consists of over 3 million records and over 10 million nested elements.
Naturally I am using xmltextreader and have got my parsing time down to about 40 seconds from earlier 90 seconds using multiple optimization tricks and tips.
But I want to further save processing time as much as I can hence below question.
Quite a few elements are of type xs:boolean and the data provider always represents values as "true" or "false" - never "1" or "0".
For such cases my earliest code was:
if (xmlTextReader.Value == "true")
{
bool subtitled = true;
}
which i further optimized to:
if (string.Equals(xmlTextReader.Value, "true", StringComparison.OrdinalIgnoreCase))
{
bool subtitled = true;
}
I wanted to know if below would be fastest (because its either "true" or "false")?
if (xtr.value.length == 4)
{
bool subtitled = true;
}
Yes, it is faster, because you only compare exactly one value, namely the length of the string.
By comparing two strings with each other, you compare each and every character, as long as both characters are the same. So if you're finding a match for the string "true", you're going to do 4 comparisons before the predicate evaluates to true.
The only problem you have with this solution is, that if someday the value is going to change from true to let's say 1, you're going to run into a problem here.
Comparing length will be faster, but less readable. I wouldn't use it unless I profile the performance of the code and conclude that I need this optimization.
What about comparing the first character to "t"?
Should (maybe :) be faster than comparing the whole string..
Measuring the length would almost invariably be faster. That said, unless this is an experiment in micro-optimization, I'd just focus on making the code to be readable and convey the proper semantics.
You might also try something like that uses the following approach:
Boolean.TryParse(xmlTextReader.Value, out subtitled)
I know that has nothing to do with your question, but I figured I'd throw it out there anyway.
Cant you just write a unit test? Run each scenario for example 1000 times and compare the datetimes.
If you know it's either "true" or "false", the last snippet must be fastest.
Anyway, you can also write:
bool subtitled = (xtr.Value.length == 4);
That should be even faster.
Old question I know but the accepted answer is wrong, or at least, incorrect in it's explanation.
Comparing the lengths maybe be the slightest bit faster but only because string.Equals is likely doing some other comparisons before it too checks the lengths and decides that they are not equal strings.
So in practice this is an optimization of last resort.
Here you can find the source for .NET core string comparison.
String comparing and parsing is very slow in .Net, I'd recommend avoid intensive using string parsing/comparing in .Net.
If you're forced to do it -- use highly optimized unmanaged or unsafe code and use parallelism.
IMHO.
I am comparing some CHAR data in a where clause in my sql like this,
where PRI_CODE < PriCode
The problem I am having is when the CHAR values are of different lengths.
So if PRI_CODE = '0800' and PriCode = '20' it is returning true instead of false.
It looks like it is comparing it like this
'08' < '20'
instead of like
'0800' < '20'
Does a CHAR comparison start from the Left until one or the other values end?
If so how do I fix this?
My values can have letters in it so convering to numeric is not an option.
It's not comparing '08' with '20', it is, as you expect, comparing '0800' with '20'.
What you don't seem to expect, however, is that '0800' (the string) is indeed less than '20' (the string).
If converting it to numerics for a numeric comparison is out of the question, you could use the following DB2 function:
right ('0000000000'||val,10)
which will give you val padded on the left with zeroes to a size of 10 (ideal for a CHAR(10), for example). That will at least guarantee that the fields are the same size and the comparison will work for your particular case. But I urge you to rethink how you're doing things: per-row functions rarely scale well, performance-wise.
If you're using z/OS, you should have a few DBAs just lying around on the computer room floor waiting for work - you can probably ask one of them for advice more tailored to your specific application :-)
One thing that comes to mind in the use of an insert/update trigger and secondary column PRI_CODE_PADDED to hold the PRI_CODE column fully padded out (using the same method as above). Then make sure your PriCode variable is similarly formatted before executing the select ... where PR_CODE_PADDED < PriCode.
Incurring that cost at insert/update time will amortise it over all the selects you're likely to do (which, because they're no longer using per-row functions, will be blindingly fast), giving you better overall performance (assuming your database isn't one of those incredibly rare beasts that are written more than read, of course).
When I need to join two strings I use String.Format (or StringBuilder if it happens in several places in the code).
I see that some good programmers doesn't give attention to strings joining complexity and just use the '+' operator.
I know that using the '+' operator make the application to use more memory, but what about complexity?
This is an excellent article about the different string join methods by our own Jeff Atwood on Coding Horror:
(source: codinghorror.com)
The Sad Tragedy of Micro-Optimization Theater
Here is the gist of the post.
[several string join methods shown]
Take your itchy little trigger finger
off that compile key and think about
this for a minute. Which one of these
methods will be faster?
Got an answer? Great!
And.. drumroll please.. the correct
answer:
It. Just. Doesn't. Matter!
This answer assumes you are talking about the runtime complexity.
Using + creates a new string object, which means the contents of both the old string objects must be copied into the new one. With a large amount of concatenation, such as in a tight loop, this can turn into an O(n^2) operation.
As an informal proof, say you had the following code:
string foo = "a";
for(int i = 0; i < 1000; i++)
{
foo += "a";
}
The first iteration of the loop, first the contents of foo ("a") are copied into a new string object, then the contents of the literal "a". That's two copies. The second iteration has three copies; two from the new foo, and one from the literal "a". The 1000th iteration will have 1001 copy operations. The total number of copies is 2 + 3 + ... + 1001. In general, if in a loop you are only concatenating one character each iteration (and you start at one character long), if the number of iterations is n, there will be 2 + 3 + ... + n + 1 copies. That's the same as 1 + 2 + 3 + ... + n = n(n+1)/2 = (n^2 + n)/2, which is O(n^2).
Depends on the situation. The + can sometimes reduce the complexity of the code. Consider the following code:
output = "<p>" + intro + "</p>";
That is a good, clear line. No String.Format required.
If you use + only once, you have no disadvantage from it and it increases readability (as Colin Pickard already stated).
As far as I know + means: take left operand and right operand and copy them into a new buffer (as strings are immutable).
So using + two times (as in Colin Pickards example you already create 2 temporary strings. First when adding "<p>" to intro and then when adding "</p>" to the newly created string.
You have to consider for yourself when to use which method. Even for a small example like seen above performance drop can be serious if intro is a large enough string.
Unless your application is very string-intensive (profile, profile, profile!), this doesn't really matter. Good programmers put readability above performance for mundane operations.
I think in terms of complexity you trade reiteration of newly created strings for parsing format string.
For axample "A" + "B" + "C" + "D" means that you would have to copy "A", "AB", and at last "ABC" in order to form "ABCD". Copying is reiteration, right? So if for example you have a 1000 character string that you will sum with thousand one character strings you will copy (1000+N) character strings 1000 times. It leads to O(n^2) complexity in worst cases.
Strin.Fomat, even considering parsing, and StringBuffer should be around O(n).
Because strings are immutable in languages like Java and C#, everytime two strings are concatenated a new string has to be created, in which the contents of the two old strings are copied.
Assume strings which are on average c characters long.
Now the first concatenation only has to copy 2*c characters, but the last one has to copy the concatenation of the first n-1 strings, which is (n-1)*c characters long, and the last one itself, which is c characters long, for a total of n*c characters. For n concatenations this makes n^2*c/2 character copies, which means an algorithmic complexity of O(n^2).
In most cases in practice however this quadratic complexity will not be noticeable (as Jeff Atwood shows in the blog entry linked to by Robert C. Cartaino) and I'd advise to just write the code as readable as possible.
There are cases however when it does matter, and using O(n^2) in such cases may be deadly.
In practice I've seen this for example for generating big Word XML files in memory, including base64 encoded pictures. This generation used to take over 10 minutes due to using O(n^2) string concatenation. After I replaced concatenation using + with StringBuilder the running time for the same document reduced below 10 seconds.
Similarly I've seen a piece of software that generated an epically big piece of SQL code as a string using + for concatenation. I haven't even waited till this finished (had been waiting for over an hour already), but just rewrote it using StringBuilder. This faster version finished within a minute.
In short, just do whatever is most readable / easiest to write and only think about this when you'll be creating a freaking huge string :-)
StringBuilder should be used if you are building a large string in several steps. It also is a good thing if you know about how large it will be eventually, then you can initialize it with the size you need, and prevent costing re-allocations. For small operations it will not be considerable performance loss using the + operator, and it will result in clearer code (and faster to write...)
Plenty of input already, but I've always felt that the best way to approach the issue of performance is to understand the performance differences of all viable solutions and for those that meet performance requirements, pick the one that is the most reliable and the most supportable.
There are many who use Big O notation to understand complexity, but I've found that in most cases (including understanding which string concatenation methods work best), a simple time trial will suffice. Just compare strA+strB to strA.Append(strB) in a loop of 100,000 iterations to see which works faster.
The compiler optimizes string literal concatenation into one string literal. For example:
string s = "a" + "b" + "c";
is optimized to the following at compile time:
string s = "abc";
See this question and this MSDN article for more information.
Compiler will optimize: "a" + "b" + "c" to be replaced with String.Concat method (not String.Format one as fixed me comments)
I benchmarked this forever ago, and it hasn't really made a differences since .NET 1.0 or 1.1.
Back then if you had some process that was going to hit a line of code that was concatinating strings a few million times you could get a huge speed increase by using String.Concat, String.Format, or StringBuilder.
Now it doesn't matter at all. At least it hasn't mattered since .Net 2.0 came out anyhow. Put it out of your mind and code in whatever manner makes it easiest for you to read.