Dart:检查字符串中特定符号是否为数字的最快方法是什么?

And*_*kin 4 dart

当然,我可以通过将其与 10 位数字进行比较甚至使用正则表达式来实现,但我正在寻找可能的最快方法。

这是我目前想到的,看起来合理吗?

int _zero = "0".codeUnits[0];
int _nine = "9".codeUnits[0];
bool isDigit(String s, int idx) => 
 s.codeUnits[idx] >= _zero && s.codeUnits[idx] <= _nine; 
Run Code Online (Sandbox Code Playgroud)

我有点惊讶我没有在标准库中找到这个方法,希望我只是错过了它。

lrn*_*lrn 8

尝试:

bool isDigit(String s, int idx) => (s.codeUnitAt(idx) ^ 0x30) <= 9;
Run Code Online (Sandbox Code Playgroud)

为了速度。

  • 我知道这是一个老问题,但我只是想指出这个方法(现在)在 quiver 包中可用。https://pub.dev/documentation/quiver/latest/quiver.strings/isDigit.html (2认同)

Pix*_*ant 6

I ran a quick micro-benchmark for the various alternatives and it seems it is pretty much a tie between Günter's method and brute force checking. I prefer Günter's method for the elegance but if performance is absolutely critical, it seems brute force may win by a tiny margin. The benchmark 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";
}
Run Code Online (Sandbox Code Playgroud)

0.045421617878512024 us.

Günter's method:

bool isDigit(String s, int idx) =>
  "0".compareTo(s[idx]) <= 0 && "9".compareTo(s[idx]) >= 0;
Run Code Online (Sandbox Code Playgroud)

0.054188391470161947 us

Your code unit method:

int _zero = "0".codeUnits[0];
int _nine = "9".codeUnits[0];
bool isDigit(String s, int idx) => 
 s.codeUnits[idx] >= _zero && s.codeUnits[idx] <= _nine;
Run Code Online (Sandbox Code Playgroud)

0.6344102870896872 us

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

 bool isDigit(String s, int idx) {
     int cuIdx = s.codeUnits[idx];
     cuIdx  >= _zero && cuIdx  <= _nine;
 }
Run Code Online (Sandbox Code Playgroud)

0.29245961607948817 us

Regex method:

RegExp digitRegExp = new RegExp(r'\d');
bool isDigit(String s, int idx) => s[idx].contains(digitRegExp);
Run Code Online (Sandbox Code Playgroud)

4.812064808888846我们

int.parse 方法(非常慢):

bool isDigit(String s, int idx) {
  bool isDigit = true;
  try {
    int.parse(s[2]);
  } catch (e) {
    isDigit = false;
  }
  return isDigit;
}
Run Code Online (Sandbox Code Playgroud)

102.48526774276198 我们