I had a good time messing about with code annotations last night. Ostensibly I am still working on the Flyweight Pattern in Dart for the forthcoming Design Patterns in Dart. Tonight, however, I am really just exploring annotations a little further.
I am somewhat surprised that the DartPad for last night's code (https://dartpad.dartlang.org/c7dabc0c57a93e8d88d7) compiled. I am a little fuzzy on the details of DartPad, but there has to be some JavaScript compilation taking place to make it work. The thing is, when I compile last night's code into JavaScript, it is huge.
The code itself is a little over 4k of Dart:
$ ls -lh bin/coffee_orders.dart lib/coffee_shop.dart -rwxr-xr-x 1 chris chris 1.6K Nov 21 00:12 bin/coffee_orders.dart -rw-r--r-- 1 chris chris 2.8K Nov 21 00:18 lib/coffee_shop.dartBut when I compile it:
$ dart2js bin/coffee_orders.dart -o bin/tmp.js bin/coffee_orders.dart: Warning: **************************************************************** * WARNING: dart:mirrors support in dart2js is experimental, * and not recommended. * This implementation of mirrors is incomplete, * and often greatly increases the size of the generated * JavaScript code. * * Your app imports dart:mirrors via: * coffee_orders.dart => package:flyweight_code => dart:mirrors * * You can disable this message by using the --enable-experimental-mirrors * command-line flag. * * To learn what to do next, please visit: * http://dartlang.org/dart2js-reflection **************************************************************** Hint: 2 hint(s) suppressed in package:flyweight_code. Hint: When run on the command-line, the compiled output might require a preamble file located in:I get nearly 4k of console warnings./lib/_internal/js_runtime/lib/preambles. bin/coffee_orders.dart: Hint: 2367 methods retained for use by dart:mirrors out of 3519 total methods (67%). bin/packages/flyweight_code/coffee_shop.dart:4:1: Info: This import is not annotated with @MirrorsUsed, which may lead to unnecessarily large generated code. Try adding '@MirrorsUsed(...)' as described at https://goo.gl/Akrrog. import 'dart:mirrors'; ^^^^^^^^^^^^^^^^^^^^^^
I kid, I kid. What is not funny however, is that, as the warning suggests, I get very large JavaScript output:
ls -lh bin/tmp.js -rw-r--r-- 1 chris chris 1.7M Nov 21 00:25 bin/tmp.js1.7Mb is insane.
The code works (if I follow the warning about preambles):
$ cat ~/local/dart/dart-sdk/lib/_internal/js_runtime/lib/preambles/d8.js bin/tmp.js > bin/coffee_orders.dart.js $ node bin/coffee_orders.dart.js Served Cappuccino to Fred. Served Espresso to Bob. Served Frappe to Alice. Served Frappe to Elsa. Served Coffee to null. Served Coffee to Chris. Served Mochachino to Joy. ----- Served 7 coffee drinks. Served 5 kinds of coffee drinks. For a profit of: $27.2But 1.7Mb is not going to fly.
I annotated my concrete flyweight classes with the
Flavor
constant:// Annotation Class class Flavor { const Flavor(); } // Annotation instance const flavor = const Flavor(); @flavor class Cappuccino implements CoffeeFlavor { String get name => 'Cappuccino'; double get profitPerOunce => 0.35; } // Other concrete instances...So, I ought to be able to slim the resultant JavaScript down simply by telling
dart2js
that it only has to worry about mirrors for Flavor
. This is what the @MirrorsUsed
annotation does. In my case, I am using mirrors as "meta targets" -- reading annotation / metadata from the code itself. I add the corresponding @MirrorsUsed()
annotation before the import of dart:mirrors
:library coffee_shop; @MirrorsUsed(metaTargets: "coffee_shop.Flavor") import 'dart:mirrors'; // ...Now, when I compile my code,
dart2js
only retain 38 methods for use with mirrors instead of 2367:$ dart2js bin/coffee_orders.dart -o bin/tmp.js --enable-experimental-mirrors bin/coffee_orders.dart: Hint: 38 methods retained for use by dart:mirrors out of 629 total methods (6%). bin/packages/flyweight_code/coffee_shop.dart:4:1: Info: Import of 'dart:mirrors'. import 'dart:mirrors'; ^^^^^^^^^^^^^^^^^^^^^^That is bound to lead to some smaller compiled code. And indeed, it comes in nearly 90% smaller than before:
$ cat ~/local/dart/dart-sdk/lib/_internal/js_runtime/lib/preambles/d8.js bin/tmp.js > bin/coffee_orders.dart.js $ ls -lh bin/tmp.js bin/coffee_orders.dart.js -rw-r--r-- 1 chris chris 294K Nov 21 00:36 bin/coffee_orders.dart.js -rw-r--r-- 1 chris chris 284K Nov 21 00:35 bin/tmp.jsThat seems a fine stopping point for tonight. I will continue this exploration tomorrow with reflectable, a potential replacement for
dart:mirrors
.Day #9
Yes, DartPad uses dart2js to compile your Dart into JavaScript so that it can run in your browser.
ReplyDeleteI am also looking at reflectable, and am going you can save me some research with your next post.
ReplyDeleteI am also looking at reflectable, and am going you can save me some research with your next post.
ReplyDelete