views:

669

answers:

5

Was doing some benchmarking with IsNumeric today and compared it to the following function:

Private Function IsNumeric(ByVal str As String) As Boolean
    If String.IsNullOrEmpty(Str) Then Return False
    Dim c As Char

    For i As Integer = 0 To Str.Length - 1
        c = Str(i)
        If Not Char.IsNumber(c) Then Return False
    Next

    Return True
End Function

I was pretty surprised with the result. With a numeric value this one was about 8-10 times faster then regular IsNumeric(), and with an empty or non-numeric value it was 1000-1500 times faster.

What is taking IsNumeric so long? Is there something else going on under the hood that I should consider before replacing it with the function above? I use IsNumeric in about 50 different places all over my site, mostly for validation of forms and query strings.

+12  A: 

Where is your check for locale-specific delimiters and decimal places? Negation? Exponential notation?

You see, your function is only a tiny subset of what numeric strings can be.

1,000,000.00
1,5E59
-123456789

You're missing all of these.

Welbog
Yes maybe I should have explained my situation better, if Im satisfied with 0-9 and maybe , and - aswell, it's still A LOT faster, was more of a question why IsNumeric() is so unreasonably slow. If there was something more to it. But maybe not :)
Cyrodor
For better results, try comparing it against Double.TryParse()
Joel Coehoorn
Or Int32.TryParse if only integers are called for.
Jon Skeet
@Cyrodor: IsNumeric() takes into account all locales, all ways of representing numbers, some of which can be very complicated. Parsing strings is just not as simple as you think it is.
Welbog
Got it, but one of the things that I found really strange was that parsing an emptry string, "", also took about 1500 times longer. So I figured there was some other functionality going on.
Cyrodor
@JonSkeet: good point. That's probably most appropriate to his need. Double.TryParse() would provide the best "apples to apples" comparison against IsNumeric(), though.
Joel Coehoorn
A: 

A single char can only contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

but a full string may contains any of the following:

1
1234
12.34
-1234
-12.34
0001

so IsNumeric ought to be somewhat slower.

There're also cultural and internationalization issues. i.e. If you are processing a Unicode string, does IsNumeric also process numbers from all other languages as well?

chakrit
A: 

Generally speaking, I would avoid duplicating or replacing language features like this, especially in a language like VB, which is bound to be implementing many use cases for you. At the very least, I would name your method something distinct so that it is not confusing to other developers.

The speed difference is bound to be the fact your code is doing far less work than the VB language feature is.

EnocNRoll
A: 

I would use

Integer.TryParse()
or
Double.TryParse()
depending on the data type you are using, since both of these account for regional differences.

Heather
A: 

Perfect solution. Many thankx

Mraadi