简体   繁体   English

dart 代码在浏览器与 VM 中的性能

[英]performance of dart code in browser vs. VM

I was surprised by the performance of my Dart code in the browser vs. the Dart VM.我对浏览器中的 Dart 代码与 Dart VM 的性能对比感到惊讶。 Here is a simple example that reproduces the issue.这是一个重现该问题的简单示例。

test('speed test', () {
    var n = 10000;
    var rand = Random(0);
    var x = List.generate(n, (i) => rand.nextDouble());

    var res = <num>[];
    var sw = Stopwatch()..start();
    for (int i=0; i<1000; i++) {
      for (int j=0; j<n; j++) {
        x[j] += i;
      }
      res.add(x.reduce((a, b) => a + b));
    }
    sw.stop();
    print('Milliseconds: ${sw.elapsedMilliseconds}');
  });

If I run this code with dart, I get somewhere around 140 milliseconds.如果我用 dart 运行这段代码,我会得到大约 140 毫秒。 If I run the same code as a browser test with pub run test -p "chrome" ... I get times around 8000 milliseconds.如果我使用pub run test -p "chrome"与浏览器测试相同的代码......我会得到大约 8000 毫秒的时间。

I am willing to wait for a 0.1 s calculation, but to wait 8 s for something in the browser, no -- it is basically unusable.我愿意等待 0.1 秒的计算,但在浏览器中等待 8 秒,不——它基本上无法使用。 When I go in release mode, the performance in browser improve but it's still 10x slower.当我在发布模式下 go 时,浏览器的性能有所提高,但仍然慢了 10 倍。

Am I missing something?我错过了什么吗? Do I have to avoid any calculations in the browser?我是否必须避免在浏览器中进行任何计算?

Thanks, Tony谢谢,托尼

It's interesting how slow this is.有趣的是这有多慢。

The corresponding JavaScript code:对应的JavaScript代码:

(function() {
  "use strict";
  var n = 10000;
  var x = [];
  var res = [];
  for (var i = 0; i < n; i++) x.push(Math.random());
  var t0 = Date.now();
  for (var i = 0; i < 1000; i++) {
    for (var j = 0; j < n; j++) {
      x[j] += i;
    }
    res.push(x.reduce((a, b) => a + b));
  }
  var t1 = Date.now();
  console.log("Milliseconds: " + (t1 - t0));
}());

runs in as little as ~20 milliseconds.只需约 20 毫秒即可运行。

So, it looks like Dart is somehow triggering "slow mode" for its generated Javascript.因此,看起来 Dart 以某种方式为其生成的 Javascript 触发了“慢速模式”。

If you look at the generated code, it contains:如果您查看生成的代码,它包含:

  for (i = 0; i < 1000; ++i) {
    for (j = 0; j < 10000; ++j) {
      if (j >= x.length)
        return H.ioore(x, j);
      t1 = x[j];
      if (typeof t1 !== "number")
        return t1.$add();
      C.JSArray_methods.$indexSet(x, j, t1 + i);
    }
    C.JSArray_methods.add$1(res, C.JSArray_methods.reduce$1(x, new A.main_closure0()));
  }

You can try to tweak this code, but the big cost comes from C.JSArray_methods.$indexSet(x, j, t1 + i);您可以尝试调整此代码,但最大的成本来自C.JSArray_methods.$indexSet(x, j, t1 + i); . . If you change that to x[j] = t1 + i;如果将其更改为x[j] = t1 + i; , the time drops to a few hundred milliseconds. ,时间下降到几百毫秒。 So, this is the problem with the current code.所以,这是当前代码的问题。

(You can improve performance a little, ~20%, by making x a List<num> instead of a List<double> . I have no idea why that makes a difference, the generated code is almost the same, the add closure uses checkDouble to check the type instead of checkNum , but they have exactly the same body). (您可以通过使x成为List<num>而不是List<double>来提高性能约 20%。我不知道为什么会有所不同,生成的代码几乎相同, add闭包使用checkDouble来检查类型而不是checkNum ,但它们具有完全相同的主体)。

You don't have to avoid any computation in the browser.您不必避免在浏览器中进行任何计算。 You may have to optimize a little for slow cases like this (or report them to the compiler developers, because this probably can be recognized and optimized, it just fails to be so for now).您可能需要针对这种缓慢的情况进行一些优化(或将它们报告给编译器开发人员,因为这可能可以被识别和优化,但目前还不能这样)。 For example, you can change your list x of doubles to a Float64List from dart:typed_data :例如,您可以将双精度列表xdart:typed_data Float64List

var x = Float64List.fromList([for (var i = 0; i < n; i++) rand.nextDouble()]);

Then speed increases quite a lot.然后速度增加了很多。

The Dart tracking issue for this is https://github.com/dart-lang/sdk/issues/38705 . Dart 跟踪问题是https://github.com/dart-lang/sdk/issues/38705

The performance of this kind of code has recently improved considerably and is much closer to the Dart VM.此类代码的性能最近有了显着提高,并且更接近 Dart VM。

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

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