converting string to array of integers fast - vb.net

What is the fastest way to convert a String into an array of Short integers representing the character codes?
I am now using this but it can probably be much faster:
Dim shortsarray(mystring.Length - 1) as Short
For i As Integer = 0 To mystring.Length - 1
shortsarray(i) = AscW(mystring.Chars(i))
Next
Thanks.

I do not know what kind of problem you are trying to solve. However, as an alternative, you could convert the string to an array of characters
Dim chars() As Char = mystring.ToCharArray()

Dim shortsarray(mystring.Length - 1) as Short //One calculation
For i As Integer = 0 To mystring.Length - 1 //One calculation, repeats n times
shortsarray(i) = AscW(mystring.Chars(i)) //Three calculations, repeats n times
Next
As a result, this should run in O(3n+1), or O(n). This is linear on the length of the input, and there isn't much improvement you can expect from that since you're doing a character-wise conversion. I think this is probably as good as you can expect, though there may be a library that will just convert the whole word in one go, making your code cleaner.
If you need performance increases, you want to first profile your whole program. This snippet may not be the problem.

Related

Why does this multiplication cause an OverflowException?

My code tries to multiply 12303 by 174596.
Any decent calculator is capable of providing an answer to this, so why do I get an OverflowException? It also happens when I execute it directly in the Immediate Window.
The code is meant to determine the position of a certain value in a binary file. The file itself is 7 Gb in size.
Is there any way to solve this?
Dim position As Long = hisFileHeader.StreamStartDataPosition +
(TSIdx * hisFileHeader.StreamDataBlockSize)
tsidx has a value of 12303 and StreamDataBlockSize has a value of 174596
I'm guessing that tsidx and StreamDataBlockSize are Integer types. The largest number an Integer type can hold is 2,147,483,647. The multiplication in brackets is then done expecting an integer result, but the answer is out of the range of Integer types. Change your code to ..
Dim position As Long = hisFileHeader.StreamStartDataPosition + (CLng(TSIdx) * hisFileHeader.StreamDataBlockSize)
and the multiplication will be done with the expectation of a Long type.

Mid() usage and for loops - Is this good practice?

Ok so I was in college and I was talking to my teacher and he said my code isn't good practice. I'm a bit confused as to why so here's the situation. We basically created a for loop however he declared his for loop counter outside of the loop because it's considered good practice (to him) even though we never used the variable later on in the code so to me it looks like a waste of memory. We did more to the code then just use a message box but the idea was to get each character from a string and do something with it. He also used the Mid() function to retrieve the character in the string while I called the variable with the index. Here's an example of how he would write his code:
Dim i As Integer = 0
Dim justastring As String = "test"
For i = 1 To justastring.Length Then
MsgBox( Mid( justastring, i, 1 ) )
End For
And here's an example of how I would write my code:
Dim justastring As String = "test"
For i = 0 To justastring.Length - 1 Then
MsgBox( justastring(i) )
End For
Would anyone be able to provide the advantages and disadvantages of each method and why and whether or not I should continue how I am?
Another approach would be, to just use a For Each on the string.
Like this no index variable is needed.
Dim justastring As String = "test"
For Each c As Char In justastring
MsgBox(c)
Next
I would suggest doing it your way, because you could have variables hanging around consuming(albeit a small amount) of memory, but more importantly, It is better practice to define objects with as little scope as possible. In your teacher's code, the variable i is still accessible when the loop is finished. There are occasions when this is desirable, but normally, if you're only using a variable in a limited amount of code, then you should only declare it within the smallest block that it is needed.
As for your question about the Mid function, individual characters as you know can be access simply by treating the string as an array of characters. After some basic benchmarking, using the Mid function takes a lot longer to process than just accessing the character by the index value. In relatively simple bits of code, this doesn't make much difference, but if you're doing it millions of times in a loop, it makes a huge difference.
There are other factors to consider. Such as code readability and modification of the code, but there are plenty of websites dealing with that sort of thing.
Finally I would suggest changing some compiler options in your visual studio
Option Strict to On
Option Infer to Off
Option Explicit to On
It means writing more code, but the code is safer and you'll make less mistakes. Have a look here for an explanation
In your code, it would mean that you have to write
Dim justastring As String = "test"
For i As Integer = 0 To justastring.Length - 1 Then
MsgBox( justastring(i) )
End For
This way, you know that i is definitely an integer. Consider the following ..
Dim i
Have you any idea what type it is? Me neither.
The compiler doesn't know what so it defines it as an object type which could hold anything. a string, an integer, a list..
Consider this code.
Dim i
Dim x
x = "ab"
For i = x To endcount - 1
t = Mid(s, 999)
Next
The compiler will compile it, but when it is executed you'll get an SystemArgumenException. In this case it's easy to see what is wrong, but often it isn't. And numbers in strings can be a whole new can of worms.
Hope this helps.

String with a list of number increment by 1 until it reach the specified number

If i have a number e.g: 5, I would to have a string that have the number that start from zero and increment by 1 until it reaches the specified number. The output is something like this "0_1_2_3_4_5"
What is the best way to do this?
As I've said earlier, there is no "best" way to do something basic like this. Use whatever approach you're comfortable with, as long as you're not doing anything horribly wrong.
Eg. one approach would be:
Dim myInt As Integer = 5
Dim result As String = String.Join("_", Enumerable.Range(0, myInt).Select(Function(x) x.ToString()))
Edit: Durr, I've been working with C# too long. Forgot how to declare variables in VB.Net. Fixed now.

Is there a way to use a nonlinear stepsize in a vb.net loop?

I would like to do the following c statement in vb.
for(int i = 2^20; i > 0; i/=2)
{
printf("%d\n",i);
}
In vb would look similar to:
For i As Integer = 2^32 to 0 Step /2
Console.Out.Writeline("{0}", i)
Next
Specifically, the variable where i is divided by 2 each iteration is not
legal vb.
Is there a way to write this using a For statement that is allowed?
No, the FOR loop in VB is shorter but less flexible.
And the obvious work-around is of course a While loop.
' untested
Dim i As Integer = 2^30 ' 2^32 will overflow
While i >= 0
Console.Writeline("{0}", i)
i = i Div 2
End While
There are two typical approaches:
Derive a formula to convert a linear (preferably integer-value) index into whatever values are needed for the loop, and then employ such a formula.
Use a method to generate one or more "IEnumerable"s to return the proper values in sequence and then replace the "For" with a "For Each"
The former approach is the one I usually use; I believe LINQ includes some methods to facilitate the latter approach (something like Enumerable.Range) but I don't know the details.

adding variables numical values (newb question)

Yesterday i had a look at how to set values of variables from nummbers stored in external txt files
the variables then needed to be added up so i used trial and error first
((XVAL) + (NEWVAL))
assuming that XVAL was set to 10 and NEWVAL was set to 20 i expected to get the answer of thirty but waqs presented with the new value of 10 20
VB.net pysicaly added the two values together but i wanted the mathematical product of the two which is ((10) + (20)) = 30
yep its a newb question could anyone explain how to achieve what im affter
XVAL and NEWVAL are strings, so they are simply being concatenated together. You need to convert them to integers, so that VB.NET will treat them as such. To do this, use the Int32.Parse() method.
Dim intXVAL As Integer = Int32.Parse(XVAL)
Dim intNEWVAL as Integer = Int32.Parse(NEWVAL)
Dim result = intXVAL + intNEWVAL
You want to cast them to a number first.
Try CDbl.
See http://msdn.microsoft.com/en-us/library/Aa263426 for more.
edit: Oops, thought you were talking about VBA.
Try using Double.Parse(YOURVALUE) if you're talking about VB.NET.
Have you tried the Val() function?
Val(XVAL) + Val(NEWVAL)
The + operator in VB.NET (for backwards-compatibility reasons) means both add and concatenate depending on the types of the variables it is being used with. With two numeric types (Integer, Single, Double, etc.), it adds the values together as you would expect. However, with String types, it concatenates the two strings.
Presumably, then, your XVAL and NEWVAL variables are String types because they're being read out of a text file, which is causing VB.NET to concatenate them into a new string instead of add them together. To get the behavior you're expecting, you need to convert them to numeric types.
Some of the other answers suggest casting simply casting the string values to numeric types (CInt, CSng, CDbl, etc.), but this may not work as expected if the value contained by your string cannot be converted to number. The Int32.Parse method will throw an exception if the value held by your string cannot be represented as a number. This is especially important to keep in mind if you're reading values from a text file that are not guaranteed to adhere to any particular constraints.
Instead, you probably want to use something like Int32.TryParse, which returns a Boolean value indicating whether or not the conversion succeeded and will not throw an exception.
As you are reading from a text file I assume that you are reading your values out as strings, so when you do this:
((XVAL) + (NEWVAL))
It is effectively concatenating the two strings together. In order to get the mathematical product of the two values these need to be int/integers which is the number type.
There are a number of ways you can do this, but in essence you have to 'cast' the strings to ints and then do your calculation.
So in vb.net it would be something like this (pseudo code):
Dim xval As String = "10"
Dim newval As String = "20"
Dim x As Integer = Int32.Parse(xval)
Dim n As Integer = Int32.Parse(newval)
Dim prod As Integer = x + n
Console.WriteLine(prod)
There are a number of other methods of doing this, for example using:
int.Parse(...)
or
Integer.TryParse(...)
More information on these sorts of type conversions can be found here:
http://dotnetperls.com/integer-parse-vbnet
One thing to bear in mind with these sorts of conversions is that you have to be certain that your input data is convertable. Otherwise your code will throw exceptions. This is where TryParse is useful as you can use this to check the inputs and handle invalid inputs without the need for exceptions.