简体   繁体   English

Dart `startsWith` 是否比 JavaScript 中的相同方法慢?

[英]Is Dart `startsWith` mega slower than the same method in JavaScript?

A link to a benchmark test in DartPad that executes Dart code, compiling it to JavaScript. DartPad 中执行 Dart 代码并将其编译为 JavaScript 的基准测试的链接。

https://dartpad.dev/?id=e110b8bc0ad72298517fb286d21bccdc https://dartpad.dev/?id=e110b8bc0ad72298517fb286d21bccdc

Test code is simple测试代码很简单

void _test1(int count) {
  final source = ' 123 ';
  for (var i = 0; i < count; i++) {
    var x = source.startsWith('123', 1);
  }
}

void _test2(int count) {
  final source = ' 123 ';
  for (var i = 0; i < count; i++) {
    var ok = source.codeUnitAt(1) == 0x31 &&
        source.codeUnitAt(2) == 0x32 &&
        source.codeUnitAt(3) == 0x33;
    var x = ok;
  }
}

Results for JavaScript: JavaScript 的结果:

Time passed: 0.000, Test 'startsWith': 105.4 ms
Time passed: 0.106, Test 'codeUnitAt': 87.8 ms
Time passed: 0.194, Test 'startsWith': 86.7 ms
Time passed: 0.280, Test 'codeUnitAt': 87.101 ms
Time passed: 0.368, Test 'startsWith': 87 ms
Time passed: 0.455, Test 'codeUnitAt': 87.2 ms
Time passed: 0.542, Test 'startsWith': 86.699 ms
Time passed: 0.629, Test 'codeUnitAt': 85.6 ms
Time passed: 0.715, Test 'startsWith': 85.7 ms
Time passed: 0.801, Test 'codeUnitAt': 86.6 ms

No questions.没有问题。

Results for Dart (JIT):飞镖 (JIT) 的结果:

Time passed: 0.000, Test 'startsWith': 837.2 ms
Time passed: 0.842, Test 'codeUnitAt': 125.094 ms
Time passed: 0.968, Test 'startsWith': 924.482 ms
Time passed: 1.892, Test 'codeUnitAt': 131.861 ms
Time passed: 2.024, Test 'startsWith': 736.603 ms
Time passed: 2.761, Test 'codeUnitAt': 76.636 ms
Time passed: 2.838, Test 'startsWith': 792.341 ms
Time passed: 3.631, Test 'codeUnitAt': 61.732 ms
Time passed: 3.693, Test 'startsWith': 721.816 ms
Time passed: 4.415, Test 'codeUnitAt': 73.93 ms

85.7 ms vs 721.816 ms 85.7 毫秒与 721.816 毫秒

These results raise a huge number of questions and the main one is: "Why startsWith is so slow compared to JavaScript?What is the reason?"这些结果引发了大量的问题,主要的问题是:“为什么startsWith比JavaScript 慢?原因是什么?”

Your test shows that Google Chrome are great at detecting functions that does nothing and/or functions that does end with the same result given the same input value.您的测试表明,在给定相同输入值的情况下,Google Chrome 擅长检测不执行任何操作的函数和/或以相同结果结尾的函数。

It is in general quite hard to do this kind of benchmark testing where we want some optimization being done but not too many since we have the risk of optimizing away the thing we wanted to test.一般来说,在我们希望进行一些优化但不要太多的情况下进行这种基准测试非常困难,因为我们有优化掉我们想要测试的东西的风险。

Eg your inner for-loop are just looping though the same data and saves the result in a local non-used variable.例如,您的内部 for 循环只是循环通过相同的数据并将结果保存在本地未使用的变量中。 The more clever the compiler is, the more it ends up getting rid of.编译器越聪明,它最终摆脱的就越多。

So the question quickly becomes: "what do we actual want to test here?"所以问题很快就变成了:“我们真正想在这里测试什么?”

The current test shows for sure that Dart VM are worse than Chrome when it comes to optimize the functions down to do basically nothing.当前的测试肯定表明,在优化功能方面,Dart VM 比 Chrome 更差,基本上什么都不做。

If we instead changes the test so we are enforcing both Chrome and Dart VM to be less predictable (and therefore make less optimizations), we could try something like this:如果我们改为更改测试以强制 Chrome 和 Dart VM 的可预测性降低(因此进行较少的优化),我们可以尝试这样的事情:

Random _rnd = Random();

void _test1(int count) {
  final source = ' 123 ';
  var x = false;
  for (var i = 0; i < count; i++) {
    x = source.startsWith('123', _rnd.nextBool() ? 0 : 1);
  }
  print(x);
}

Then Chrome returns (I have removed the codeUnitAt results):然后 Chrome 返回(我已经删除了codeUnitAt结果):

true
Time passed: 0.000, Test 'startsWith': 3531 ms
false
Time passed: 3.531, Test 'startsWith': 3498 ms
false
Time passed: 7.029, Test 'startsWith': 3289 ms
true
Time passed: 10.319, Test 'startsWith': 3316 ms
true
Time passed: 13.635, Test 'startsWith': 3266 ms

And Dart VM:和飞镖虚拟机:

false
Time passed: 0.000, Test 'startsWith': 2119 ms
false
Time passed: 2.121, Test 'startsWith': 1901 ms
true
Time passed: 4.023, Test 'startsWith': 2012 ms
true
Time passed: 6.035, Test 'startsWith': 1998 ms
false
Time passed: 8.033, Test 'startsWith': 2009 ms

And Dart compiled to an exe file: Dart 编译成 exe 文件:

false
Time passed: 0.000, Test 'startsWith': 1364 ms
true
Time passed: 1.365, Test 'startsWith': 1360 ms
true
Time passed: 2.726, Test 'startsWith': 1369 ms
false
Time passed: 4.095, Test 'startsWith': 1355 ms
false
Time passed: 5.451, Test 'startsWith': 1362 ms

Similar thing can also be seen if we change the codeUnitAt test.如果我们更改codeUnitAt测试,也可以看到类似的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM