I built myself a sweet little Dart code timer class last night. Tonight, I am going to make use of it to see how over-isolating things in Dart affects process speed. But first up, I need to move my class timer out into a library that can be included in subsequent iterations as I try to improve my time.
Reading through the spec, it seems like a Dart library is a simple enough thing. I only need create a separate file with a top level class (or similar declaration) and then
#import()
it. So, the separate file is:// pretty_stop_watch.dart class PrettyStopwatch { // last night's code here... }Then, in my main dart file:
// timer03.dart #import('pretty_stop_watch.dart');However, when I run this, I am greeted with:
➜ command_line git:(master) ✗ dart timer03.dart '/home/cstrom/repos/dart-site/examples/command_line/timer03.dart': Error: line 1 pos 1: library handler failed: '/home/cstrom/repos/dart-site/examples/command_line/pretty_stop_watch.dart': Error: line 1 pos 1: '#library' expected class PrettyStopwatch { ^ #import('pretty_stop_watch.dart'); ^OK. It seems that I need a bit more than just a class declaration. Let's try a
#library();
declaration at the top of the library file. I am not sure what to put in there, so I try the filename, minus the extension:#library('pretty_stop_watch'); class PrettyStopwatch { // last night's code here... }Now, when I try to run the main dart code, I get:
➜ command_line git:(master) ✗ dart timer03.dart Unable to find entrypoint: static .main()Ew.
Well, if you want a static
main()
, I can oblige:#library('pretty_stop_watch'); main() {} class PrettyStopwatch { // last night's code here... }When I run the code now, I get now errors. So that is progress.
To actually use the
PrettyStopwatch
class, I add the isolate-based doomsday solver into timer03.dart
:// timer03.dart #import('pretty_stop_watch.dart'); main() { // spawn the isolate solver } class DoomsDay extends Isolate { /* ... */ } class DoomsDayFinder extends Isolate { /* ... */ }Unfortunately, now I get the following error when I try to time with my library:
➜ command_line git:(master) ✗ dart timer03.dart '/home/cstrom/repos/dart-site/examples/command_line/timer03.dart': Error: line 3 pos 1: 'main' is already defined main() { ^Well, of course main is already defined. You insisted that I define it you stupid compiler! Oh wait...
Maybe the compiler was telling me that I needed a
main()
method in my primary file, not in my library. Duh.I leave the main
timer03.dart
script as-is and remove the main()
method from pretty_stop_watch.dart
:#library('pretty_stop_watch'); class PrettyStopwatch { // last night's code here... }And that does it. Now when I run the code, I am returned a list of all the years in the 21st century in which the doomsday is a Wednesday, followed by timing information:
➜ command_line git:(master) ✗ dart timer03.dart 2001 2007 2012 2018 2029 2035 2040 2046 2057 2063 2068 2074 2085 2091 2096 Elapsed time: 2779msI have already broken Dart importing in a couple of different ways. I wonder if there are other things I can break. For instance, that string that I supplied to the
#library()
call—what happens when I change that to something other than the filename?#library('asdf'); class PrettyStopwatch { // ... }As it turns out, nothing. The code still runs just fine.
In the end, I opt for a somewhat descriptive title for the library:
#library('A very pretty stop watch class'); // ...It seems silly to duplicate the classname or the filename here. I was able to find
#library()
in the spec (scrolling helps), but it offers no suggestions for what to use here.One other thing that I try is uploading my pretty stop watch library to github in the hopes of importing it over the network. This, however does not work from the command line:
➜ command_line git:(master) ✗ dart timer04.dart '/home/cstrom/repos/dart-site/examples/command_line/timer04.dart': Error: line 1 pos 1: library handler failed: Unable to open file: /home/cstrom/repos/dart-site/examples/command_line/https://raw.github.com/dart4hipsters/dart4hipsters.github.com/master/examples/lib/pretty_stopwatch.dart #import('https://raw.github.com/dart4hipsters/dart4hipsters.github.com/master/examples/lib/pretty_stopwatch.dart'); ^Nor does it work on try.dartlang.org. I was none too sure about either (although it would have been cool if it had worked). Hopefully it will work when I try this out in Dartium another day.
Anyhow, I have my very excellent stop watch class factored out into a class library. I also see that my isolate-intensive doomsday solver is taking 2.8 seconds. Let's use my stopwatch class to time a non-isolate solution:
#import('pretty_stopwatch.dart'); main() { var century = 2000 , matching_years = []; var timer = new PrettyStopwatch.start(); for (var i=0; i <100; i++) { var year = century + i , doomsday = find_doomsday_for(year); if (doomsday == 'Wed') matching_years.add(year); } for (var year in matching_years) print(year); timer.stop(); } find_doomsday_for(year) { var march1 = new Date(year, 3, 1, 0, 0, 0, 0) , doom = march1.subtract(new Duration(1)).weekday , dow = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun']; return dow[doom]; }(try.dartlang.org with PrettyStopwatch embedded)
The result? A complete denouncement of my isolate approach:
➜ command_line git:(master) ✗ dart timer05.dart 2001 2007 2012 ... 2091 2096 Elapsed time: 49msAdmittedly, 49 milliseconds is slightly better than 2.8 seconds, but this is not an indictment of isolates, just an indictment of the appropriateness of using them to solve a fairly simple problem like this.
This will do for a stopping point today. Up tomorrow: hopefully finding a more appropriate use of Isolates.
Day #259
Great write up. Another thing you can do with a #library() is #source() a dart files to compose the library. http://goo.gl/m3anI If your using the DartEditor it has some bugs with creating libraries. I just close and reopen or wipe out workspace directory.
ReplyDelete@Adam Hah! I had no idea that includes were done with #source(). I read through the "Includes" section of the spec a couple of times yesterday but mentally assumed that the directive would be #include(). I couldn't figure out what you could be talking about until I re-read the spec :)
ReplyDeleteWhatever it's called, I'll definitely check out includes in the near future. Thanks!