# Dart: what's the fastest way to check if a particular character in a string is a digit?

Of course I can do this by comparing it to 10 digits or even using regular expressions, but I am looking for the fastest way.

Here's what I came up with now, does that sound reasonable?

``````int _zero = "0".codeUnits;
int _nine = "9".codeUnits;
bool isDigit(String s, int idx) =>
s.codeUnits[idx] >= _zero && s.codeUnits[idx] <= _nine;
```

```

I'm a little surprised that I didn't find this method in the standard library, I hope I just missed it.

+3

source to share

Try:

``````bool isDigit(String s, int idx) => (s.codeUnitAt(idx) ^ 0x30) <= 9;
```

```

for speed.

+4

source

Looks good to me if you are not using Unicode characters.

A similar attempt, but I would not expect this to be faster:

``````bool isDigit(String s, int idx) =>
"0".compareTo(s[idx]) <= 0 && "9".compareTo(s[idx]) >= 0;
```

```

It would be interesting if the compiler optimizes this duplicate `s[idx]`

/ `s.codeUnits[idx]`

, but I would expect it.

+3

source

I did a quick micro test for various alternatives and it looks like it is almost a link between the Günter method and brute force testing. I prefer Gunther's method for elegance, but if performance is absolutely critical, it seems like brute force can win by a small margin. The test runs each method once for an index that will return true and once for an index that will return false.

### Brute force method:

``````bool isDigit(String s, int idx) {
return s[idx] == "0"
|| s[idx] == "1"
|| s[idx] == "2"
|| s[idx] == "3"
|| s[idx] == "4"
|| s[idx] == "5"
|| s[idx] == "6"
|| s[idx] == "7"
|| s[idx] == "8"
|| s[idx] == "9";
}
```

```

0.045421617878512024.

### Gunther's method:

``````bool isDigit(String s, int idx) =>
"0".compareTo(s[idx]) <= 0 && "9".compareTo(s[idx]) >= 0;
```

```

0.054188391470161947 us

### The way your code is:

``````int _zero = "0".codeUnits;
int _nine = "9".codeUnits;
bool isDigit(String s, int idx) =>
s.codeUnits[idx] >= _zero && s.codeUnits[idx] <= _nine;
```

```

0.6344102870896872 us

This can be improved with 2x by storing the results of s.codeUnits [idx] (for some reason the VM cannot optimize it, unlike other methods where repeated calls to s [idx] are optimized and no slower than storing the intermediate result ):

`````` bool isDigit(String s, int idx) {
int cuIdx = s.codeUnits[idx];
cuIdx  >= _zero && cuIdx  <= _nine;
}
```

```

0.29245961607948817 us

### Regex method:

``````RegExp digitRegExp = new RegExp(r'\d');
bool isDigit(String s, int idx) => s[idx].contains(digitRegExp);
```

```

4.812064808888846 us

### int.parse method (extremely slow):

``````bool isDigit(String s, int idx) {
bool isDigit = true;
try {
int.parse(s);
} catch (e) {
isDigit = false;
}
return isDigit;
}
```

```

102.48526774276198 us

+2

source

All Articles