Sdk: the Map implementation in dart2js is 3 times slower than JS version

Created on 28 Dec 2016  Â·  4Comments  Â·  Source: dart-lang/sdk

For example,

The dart version will take about 2738 ms in my environment.

import 'dart:collection';
void main() {
  var m1 = {};
  var s = new DateTime.now().microsecondsSinceEpoch;
  for (var i = 0; i < 1000000; i++) {    
    var m2 = {};
    m1[i] = m2;
    m2[i] = i;
  }
  print(new DateTime.now().microsecondsSinceEpoch - s);
}

The pure JS version will take about 813 ms only.

var s = new Date().getTime();
var m1 = {};
 for (var i = 0; i < 1000000; i++) {    
    var m2 = {};
    m1[i] = m2;
    m2[i]  = i;
 }
console.log(new Date().getTime() - s);

I also tested the dart version in dart VM, it takes the same as the pure JS version.
So, it seems no way for us to optimize the Map creation to speed up the performance in browser environment.

area-web web-dart2js

Most helpful comment

Stephen does it make sense to expose a specialized "map" that delegates
almost directly to an anonymous object in JS for perf sensitive scenarios
where it would make sense?

On Tue, Jan 10, 2017, 10:20 AM Stephen Adams notifications@github.com
wrote:

They are not really comparable.

  • Dart Maps remember the insertion order.
  • Dart map keys are compared with the user defined == operator. No
    JavaScript maps have this feature.
  • JS objects only take string (and symbol) 'keys', so m[1] and m["1"]
    are the same.
  • JS objects do not properly remember the insertion order of numeric
    'keys'.
  • JS objects have false hits e.g. var a= {}; print(a['toString'])
  • If you do m['__proto__'] = ... on a JS object you get crazy results.

Dart Maps fix these problems (and others).
A lot of the difference is attributable to fixing these problems.

You could try using new HashMap() in Dart if you don't care about
preservation of insertion order.

The VM is faster because is it just faster at some kinds of code (the VM
Map implementation is mostly written in Dart.)

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/sdk/issues/28210#issuecomment-271654609,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKQ7tbFcCQMvif_WYvs68R4ZenRHbhPks5rQ8vhgaJpZM4LWtrL
.

All 4 comments

They are not really comparable.

  • Dart Maps remember the insertion order.
  • Dart map keys are compared with the user defined == operator. No JavaScript maps have this feature.
  • JS objects only take string (and symbol) 'keys', so m[1] and m["1"] are the same.
  • JS objects do not properly remember the insertion order of numeric 'keys'.
  • JS objects have false hits e.g. var a= {}; print(a['toString'])
  • If you do m['__proto__'] = ... on a JS object you get crazy results.

Dart Maps fix these problems (and others).
A lot of the difference is attributable to fixing these problems.

You could try using __new HashMap()__ in Dart if you don't care about preservation of insertion order.

The VM is faster because is it just faster at some kinds of code (the VM Map implementation is mostly written in Dart.)

Stephen does it make sense to expose a specialized "map" that delegates
almost directly to an anonymous object in JS for perf sensitive scenarios
where it would make sense?

On Tue, Jan 10, 2017, 10:20 AM Stephen Adams notifications@github.com
wrote:

They are not really comparable.

  • Dart Maps remember the insertion order.
  • Dart map keys are compared with the user defined == operator. No
    JavaScript maps have this feature.
  • JS objects only take string (and symbol) 'keys', so m[1] and m["1"]
    are the same.
  • JS objects do not properly remember the insertion order of numeric
    'keys'.
  • JS objects have false hits e.g. var a= {}; print(a['toString'])
  • If you do m['__proto__'] = ... on a JS object you get crazy results.

Dart Maps fix these problems (and others).
A lot of the difference is attributable to fixing these problems.

You could try using new HashMap() in Dart if you don't care about
preservation of insertion order.

The VM is faster because is it just faster at some kinds of code (the VM
Map implementation is mostly written in Dart.)

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/dart-lang/sdk/issues/28210#issuecomment-271654609,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKQ7tbFcCQMvif_WYvs68R4ZenRHbhPks5rQ8vhgaJpZM4LWtrL
.

@rakudrama But if you use something like angular 2 and browser you want performant js code, not performant dart vm code. So it'll be useful for this cases use js object.

@matanlurey That is how dart2js's Maps are implemented - they delegate to a JS object (Object.create(null)).

This is true of both LinkedHashMap (the default Map) and HashMap.

Much of the cost in the above test is due to the tests done before using the JS object to make sure it is safe, and in making sure we get the correct result for .length and when null is stored as the value.

When we last experimented with using ES6 Maps (they are closer to what we need, so less overhead before delegating) the performance was worse. Long term, using ES6 Maps more is the right thing to do.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sgrekhov picture sgrekhov  Â·  3Comments

ranquild picture ranquild  Â·  3Comments

55555Mohit55555 picture 55555Mohit55555  Â·  3Comments

xster picture xster  Â·  3Comments

nex3 picture nex3  Â·  3Comments