September 14th, 2007
Converting a string to an integer is a common operation and there are several ways to do this in VB.NET. In this article, we’ll take a look at several of them and compare them and, perhaps, arrive at the best all round way to perform this operation.
I’ll be rating each function on 3 factors: Usability, Flexibility and Performance. Usability indicates how easy it is for the average programmer to understand how to use it and get the desired results. Flexibility is how many overloads are available for it and how well it integrates with the rest of VB.NET and the .NET world as a whole. Performance is how well the function does in my speed test, a loop of 10000 iterations calling the function with a string variable equal to “1000″. Each criteria is on a scale of 1 to 5 with 5 being the best.
Val is the venerable BASIC conversion command. It’s been around since the very early days of the BASIC language in the mid to late 1960s. In older versions of MSBASIC it was the only game in town when it came to conversions. It’s still in VB.NET, as a member of the Microsoft.VisualBasic.Conversion namespace, and it really hasn’t changed much from the old days. It reads in a string and looks for numerics or numeric modifiers (”.”, “+”, “-”, “&H”, “&O”). It strips out whitespace characters as it goes and it stops on the first character that’s not numeric according to its criteria. It returns a double, not an integer, so, if you’re running Option Strict like you should, an extra conversion step is needed to make an integer. It also cannot interpret cultural information, such as different decimal separators.
MyDouble = Val(MyString)
Usability: Programmers moving over from VB6 or earlier BASIC may be familiar with it and its quirks but its conversion methods can easily introduce unexpected bugs into a program. Rating: 2
Flexibility: It has 3 overloads, accepting a String, Char, or Object. It won’t throw an exception except in the case of an unconvertable object or an overflow error. Rating: 3
Performance: Amazingly, Val turned in the fastest performance in my testing, beating out the other methods. It was 3 times faster than Parse and nearly 6 times faster than CInt. It’s a 60’s muscle car of a function, fast on the straight track but not so great on curves. Rating: 5
CInt is another classic MSBASIC conversion method. It hasn’t been around quite as long as Val but made its debut in the 1980’s in QuickBasic. One ‘old school’ difference between it and VAl is that it will throw an error if the string in question can’t be converted. Unlike Val, it is part of the core VB.NET language and is not, as some mistakenly believe, part of the much maligned Microsoft.VisualBasic namespace.
MyInteger = CInt(MyString)
Usability: It’s an easy and familar command that’s very straightforward to use and quite readable. It uses “Banker’s Rounding” to round off fractions, which can be a plus or minus depending on your perspective. Rating: 4
Flexibility: It takes an Object as a parameter which makes it somewhat flexible, perhaps too much so. It does handle the current cultural settings fine but you can’t use alternative providers. Rating 3
Performance: MSDN recommends that you use CInt and the other ‘C’ conversion functions because they’re optimized for VB.NET code. To my surprise, my testing didn’t show this optimization. Instead, it turned in the slowest time of all the functions. Rating: 1
Parse is a new .NET function built into the numeric data types. If you want to do things the .NET way, it’s your ticket. And, as we’ll see below, it’s quite flexible.
MyInteger = Integer.Parse(MyString)
Usability: This function, while something new to .NET newbies, is easy enough to understand for novices. For experienced VB.NET programmers the flexibility makes it a good choice: Rating: 5
Flexibility: It has 4 overloads which allow it to accept FormatProviders and NumberStyles, making it quite flexible. The ability to use FormatProviders makes it very adaptable to applications that need to be globally aware. The NumberStyles allow acceptable character combinations to be precisely defined. The only flexibility downside is that a bad entry will cause a time consuming exception. Rating: 5
Performance: This function, while not as fast as Val, is twice as fast as CInt. Rating: 4
TryParse is brand new in the .NET Framework 2.0. It is like its cousin, Parse, with a few differences. Most notably, it does not throw an exception if the function fails, instead it returns a False. Returns a False, not an integer? That’s right, the return value from the function is a success/fail Boolean while the integer variable is passed into the function ByRef and modified by the function.
Usability: This function is a little confusing at first, since it returns a Boolean, but easily becomes comfortable. Since it doesn’t throw an exception on bad data, it can be more useful than Parse in some situations. Rating: 4
Flexibility: It has 2 overloads, the second allows it to accept FormatProviders and NumberStyles, just like Parse does. The only downside is that you can’t supply one or the other parameter, both must be specified. Rating: 5
Performance: This function returned performance numbers virtually identical to it’s cousin. It’s nimble avoidance of a potential exception slow down gives it a slight edge. Rating: 5
The Convert object in .NET is used to convert one data type into another data type and, of course, the ability to convert a String to an Integer, or Int32 in our case, is provided.
MyInteger = Convert.ToInt32(MyString)
Usability: This number of overloads for this function might be a little intimidating to some at first glance but it is rather straight forward in how it works. Bad data will throw an exception.: Rating: 5
Flexibility: ToInt32 has a whopping 19 overloads that allow it to convert just about another other data type. It can also use FormatProviders but not NumberStyles. Rating: 5
Performance: This function is about 20% slower than the Parse and TryParse functions, probably because it is doing more internally. Rating: 3
That covers the major conversion methods. There are a few others out there that I didn’t cover, such as using Regular Expressions to convert, or coding your own conversion. If you think there is one I should have covered but I didn’t, please let me know in a comment.
Now let’s look at which function is the winner of our comparison by looking at the total score.
Val - 10 Points
CInt - 8 Points
Parse - 14 Points
TryParse - 14 Points
Convert.ToInt32 - 13 Points
Parse and TryParse tie! The deciding factor of which of these to use would probably depend on your code. I tend to favor TryParse myself since it handles exceptions so gracefully so I’ll give it the tie breaker win.
CInt really turned out to be a disappointment performance-wise. I have defended this function on a few occasions when some people didn’t know it was part of the core VB.NET language. While I can still defend it on that count, its poor performance makes me not recommend it. I will note that its conversion speed was much faster for doing number to number data type conversions so this speed hit seems to be only associated with string conversions.
While I can’t recommend the use of Val due to it’s hinky conversion rules, its performance was quite surprising. It would be interesting to see how it was implemented internally.
Well, that’s it for this comparison test. Have you run any tests and gotten different results? What are your thoughts on string to integer conversion in VB.NET? Any questions? Leave me a comment.
Entry Filed under: Tip Sheets
Rate This Article: