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

时间:2014-09-16 15:13:25

标签: 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; 

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

3 个答案:

答案 0 :(得分:4)

尝试:

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

速度。

答案 1 :(得分:3)

对我来说很好,只要你不使用unicode字符。

类似的尝试,但我不希望这会更快:

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

如果编译器优化了这个重复的s[idx] / s.codeUnits[idx],那会很有趣 - 但我希望如此。

答案 2 :(得分:2)

我为各种替代方案运行了一个快速的微基准测试,看起来它与Günter's method和强力检查之间几乎是一个联系。我更喜欢Günter的优雅方法,但如果表现绝对至关重要,那么蛮力可能会以微小的优势获胜。对于将返回true的索引,以及将返回false的索引,基准测试运行每个方法一次。

暴力法:

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我们。

Günter的方法:

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

0.054188391470161947 us

您的代码单元方法:

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

0.6344102870896872 us

这可以通过存储s.codeUnits [idx]的结果来提高2倍(由于某种原因,VM无法设法优化它,不像其他方法,其中重复的s [idx]调用被优化并且不比存储中间结果):

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

0.29245961607948817 us

正则表达式方法:

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

4.812064808888846我们

int.parse方法(极慢):

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

102.48526774276198我们