blob: a8e037d983f40d39ffa48b820b244fe30b8540db [file] [log] [blame]
ager@google.com4531c0c2012-08-03 07:24:29 +00001// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
dgrove@google.com4c0f5592011-10-05 05:20:07 +00002// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
gram@google.com96016f92012-11-08 18:41:58 +00005import 'dart:isolate';
regis@google.comca927272013-02-04 05:51:02 +00006import 'dart:async';
sigmund@google.comee6a9072012-02-27 22:50:44 +00007
floitsch@google.com8fd6d0a2013-04-05 19:43:16 +00008class Expect {
9 static void equals(x, y) {
lrn@google.com662c2a82013-06-04 10:33:11 +000010 if (x != y) throw new ArgumentError('not equal');
floitsch@google.com8fd6d0a2013-04-05 19:43:16 +000011 }
12}
13
lrn@google.com37197c22012-09-27 13:07:54 +000014class Fields {
Jacob Richman4360e992017-03-21 10:07:26 -070015 Fields(int i, int j)
16 : fld1 = i,
17 fld2 = j,
18 fld5 = true {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +000019 int fld1;
20 final int fld2;
21 static int fld3;
iposva@google.com327ff5d2012-08-27 23:51:37 +000022 static const int fld4 = 10;
dgrove@google.com4c0f5592011-10-05 05:20:07 +000023 bool fld5;
24}
Jacob Richman4360e992017-03-21 10:07:26 -070025
dgrove@google.com4c0f5592011-10-05 05:20:07 +000026class FieldsTest {
27 static Fields testMain() {
28 Fields obj = new Fields(10, 20);
29 Expect.equals(10, obj.fld1);
30 Expect.equals(20, obj.fld2);
31 Expect.equals(10, Fields.fld4);
32 Expect.equals(true, obj.fld5);
33 return obj;
34 }
35}
36// Benchpress: A collection of micro-benchmarks.
37// Ported from internal v8 benchmark suite.
38
39class Error {
40 static void error(String msg) {
41 throw msg;
42 }
43}
44
45// F i b o n a c c i
46class Fibonacci {
47 static int fib(int n) {
48 if (n <= 1) return 1;
49 return fib(n - 1) + fib(n - 2);
50 }
51}
52
53class FibBenchmark extends BenchmarkBase {
54 const FibBenchmark() : super("Fibonacci");
55
56 void warmup() {
57 Fibonacci.fib(10);
58 }
59
60 void exercise() {
61 // This value has been copied from benchpress.js, so that we can compare
62 // performance.
63 var result = Fibonacci.fib(20);
64 if (result != 10946)
65 Error.error("Wrong result: $result. Should be: 10946.");
66 }
67
68 static void main() {
69 new FibBenchmark().report();
70 }
71}
72
73// L o o p
74class Loop {
75 static int loop(int outerIterations) {
76 int sum = 0;
77 for (int i = 0; i < outerIterations; i++) {
78 for (int j = 0; j < 100; j++) {
79 sum++;
80 }
81 }
82 return sum;
83 }
84}
85
86class LoopBenchmark extends BenchmarkBase {
87 const LoopBenchmark() : super("Loop");
88
89 void warmup() {
90 Loop.loop(10);
91 }
92
93 void exercise() {
94 // This value has been copied from benchpress.js, so that we can compare
95 // performance.
96 var result = Loop.loop(200);
Jacob Richman4360e992017-03-21 10:07:26 -070097 if (result != 20000) Error.error("Wrong result: $result. Should be: 20000");
dgrove@google.com4c0f5592011-10-05 05:20:07 +000098 }
99
100 static void main() {
101 new LoopBenchmark().report();
102 }
103}
104
105// T o w e r s
106class TowersDisk {
107 final int size;
108 TowersDisk next;
109
Jacob Richman4360e992017-03-21 10:07:26 -0700110 TowersDisk(size)
111 : this.size = size,
112 next = null {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000113}
114
115class Towers {
116 List<TowersDisk> piles;
117 int movesDone;
lrn@google.com3c0ac362013-02-25 10:48:09 +0000118 Towers(int disks)
Jacob Richman4360e992017-03-21 10:07:26 -0700119 : piles = new List<TowersDisk>(3),
120 movesDone = 0 {
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000121 build(0, disks);
122 }
123
124 void build(int pile, int disks) {
125 for (var i = disks - 1; i >= 0; i--) {
126 push(pile, new TowersDisk(i));
127 }
128 }
129
130 void push(int pile, TowersDisk disk) {
131 TowersDisk top = piles[pile];
floitsch@google.com8e6f2382012-11-12 17:19:58 +0000132 if ((top != null) && (disk.size >= top.size))
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000133 Error.error("Cannot put a big disk on a smaller disk.");
134 disk.next = top;
135 piles[pile] = disk;
136 }
137
138 TowersDisk pop(int pile) {
139 var top = piles[pile];
floitsch@google.com8e6f2382012-11-12 17:19:58 +0000140 if (top == null)
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000141 Error.error("Attempting to remove a disk from an empty pile.");
142 piles[pile] = top.next;
143 top.next = null;
144 return top;
145 }
146
147 void moveTop(int from, int to) {
148 push(to, pop(from));
149 movesDone++;
150 }
151
152 void move(int from, int to, int disks) {
153 if (disks == 1) {
154 moveTop(from, to);
155 } else {
156 int other = 3 - from - to;
157 move(from, other, disks - 1);
158 moveTop(from, to);
159 move(other, to, disks - 1);
160 }
161 }
162}
163
164class TowersBenchmark extends BenchmarkBase {
165 const TowersBenchmark() : super("Towers");
166
167 void warmup() {
168 new Towers(6).move(0, 1, 6);
169 }
170
171 void exercise() {
172 // This value has been copied from benchpress.js, so that we can compare
173 // performance.
174 var towers = new Towers(13);
175 towers.move(0, 1, 13);
176 if (towers.movesDone != 8191) {
177 var moves = towers.movesDone;
178 Error.error("Error in result: $moves should be: 8191");
179 }
180 }
181
182 static void main() {
183 new TowersBenchmark().report();
184 }
185}
186
187// S i e v e
188class SieveBenchmark extends BenchmarkBase {
189 const SieveBenchmark() : super("Sieve");
190
191 static int sieve(int size) {
192 int primeCount = 0;
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +0000193 List<bool> flags = new List<bool>(size + 1);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000194 for (int i = 1; i < size; i++) flags[i] = true;
195 for (int i = 2; i < size; i++) {
196 if (flags[i]) {
197 primeCount++;
Jacob Richman4360e992017-03-21 10:07:26 -0700198 for (int k = i + 1; k <= size; k += i) flags[k - 1] = false;
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000199 }
200 }
201 return primeCount;
202 }
203
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000204 void warmup() {
205 sieve(100);
206 }
207
208 void exercise() {
209 // This value has been copied from benchpress.js, so that we can compare
210 // performance.
211 int result = sieve(1000);
Jacob Richman4360e992017-03-21 10:07:26 -0700212 if (result != 168) Error.error("Wrong result: $result should be: 168");
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000213 }
214
215 static void main() {
216 new SieveBenchmark().report();
217 }
218}
219
220// P e r m u t e
221// The original benchmark uses one-based indexing. Even though arrays in JS and
222// lists in dart are zero-based, we stay with one-based indexing
223// (wasting one element).
224class Permute {
225 int permuteCount;
226 Permute() {}
227
228 void swap(int n, int k, List<int> list) {
229 int tmp = list[n];
230 list[n] = list[k];
231 list[k] = tmp;
232 }
233
234 void doPermute(int n, List<int> list) {
235 permuteCount++;
236 if (n != 1) {
237 doPermute(n - 1, list);
238 for (int k = n - 1; k >= 1; k--) {
239 swap(n, k, list);
240 doPermute(n - 1, list);
241 swap(n, k, list);
242 }
243 }
244 }
245
246 int permute(int size) {
247 permuteCount = 0;
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +0000248 List<int> list = new List<int>(size);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000249 for (int i = 1; i < size; i++) list[i] = i - 1;
250 doPermute(size - 1, list);
251 return permuteCount;
252 }
253}
254
255class PermuteBenchmark extends BenchmarkBase {
256 const PermuteBenchmark() : super("Permute");
257
258 void warmup() {
259 new Permute().permute(4);
260 }
261
262 void exercise() {
263 // This value has been copied from benchpress.js, so that we can compare
264 // performance.
265 int result = new Permute().permute(8);
Jacob Richman4360e992017-03-21 10:07:26 -0700266 if (result != 8660) Error.error("Wrong result: $result should be: 8660");
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000267 }
268
269 static void main() {
270 new PermuteBenchmark().report();
271 }
272}
273
274// Q u e e n s
275// The original benchmark uses one-based indexing. Even though arrays in JS and
276// lists in dart are zero-based, we stay with one-based indexing
277// (wasting one element).
278class Queens {
Jacob Richman4360e992017-03-21 10:07:26 -0700279 static bool tryQueens(
280 int i, List<bool> a, List<bool> b, List<bool> c, List<int> x) {
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000281 int j = 0;
282 bool q = false;
283 while ((!q) && (j != 8)) {
284 j++;
285 q = false;
286 if (b[j] && a[i + j] && c[i - j + 7]) {
287 x[i] = j;
288 b[j] = false;
289 a[i + j] = false;
290 c[i - j + 7] = false;
291 if (i < 8) {
292 q = tryQueens(i + 1, a, b, c, x);
293 if (!q) {
294 b[j] = true;
295 a[i + j] = true;
296 c[i - j + 7] = true;
297 }
298 } else {
299 q = true;
300 }
301 }
302 }
303 return q;
304 }
305
306 static void queens() {
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +0000307 List<bool> a = new List<bool>(9);
308 List<bool> b = new List<bool>(17);
309 List<bool> c = new List<bool>(15);
310 List<int> x = new List<int>(9);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000311 b[1] = false;
312 for (int i = -7; i <= 16; i++) {
313 if ((i >= 1) && (i <= 8)) a[i] = true;
314 if (i >= 2) b[i] = true;
315 if (i <= 7) c[i + 7] = true;
316 }
317
Jacob Richman4360e992017-03-21 10:07:26 -0700318 if (!tryQueens(1, b, a, c, x)) Error.error("Error in queens");
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000319 }
320}
321
322class QueensBenchmark extends BenchmarkBase {
323 const QueensBenchmark() : super("Queens");
324
325 void warmup() {
326 Queens.queens();
327 }
328
329 void exercise() {
330 Queens.queens();
331 }
332
333 static void main() {
334 new QueensBenchmark().report();
335 }
336}
337
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000338// R e c u r s e
339class Recurse {
340 static int recurse(int n) {
341 if (n <= 0) return 1;
342 recurse(n - 1);
343 return recurse(n - 1);
344 }
345}
346
347class RecurseBenchmark extends BenchmarkBase {
348 const RecurseBenchmark() : super("Recurse");
349
350 void warmup() {
351 Recurse.recurse(7);
352 }
353
354 void exercise() {
355 // This value has been copied from benchpress.js, so that we can compare
356 // performance.
357 Recurse.recurse(13);
358 }
359
360 static void main() {
361 new RecurseBenchmark().report();
362 }
363}
364
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000365// S u m
366class SumBenchmark extends BenchmarkBase {
367 const SumBenchmark() : super("Sum");
368
369 static int sum(int start, int end) {
370 var sum = 0;
371 for (var i = start; i <= end; i++) sum += i;
372 return sum;
373 }
374
375 void warmup() {
376 sum(1, 1000);
377 }
378
379 void exercise() {
380 // This value has been copied from benchpress.js, so that we can compare
381 // performance.
382 int result = sum(1, 10000);
383 if (result != 50005000)
384 Error.error("Wrong result: $result should be 50005000");
385 }
386
387 static void main() {
388 new SumBenchmark().report();
389 }
390}
391
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000392// H e l p e r f u n c t i o n s f o r s o r t s
393class Random {
iposva@google.com327ff5d2012-08-27 23:51:37 +0000394 static const int INITIAL_SEED = 74755;
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000395 int seed;
396 Random() : seed = INITIAL_SEED {}
397
398 int random() {
399 seed = ((seed * 1309) + 13849) % 65536;
400 return seed;
401 }
402}
403
404//
405class SortData {
406 List<int> list;
407 int min;
408 int max;
409
410 SortData(int length) {
411 Random r = new Random();
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +0000412 list = new List<int>(length);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000413 for (int i = 0; i < length; i++) list[i] = r.random();
414
415 int min, max;
416 min = max = list[0];
417 for (int i = 0; i < length; i++) {
418 int e = list[i];
419 if (e > max) max = e;
420 if (e < min) min = e;
421 }
422
423 this.min = min;
424 this.max = max;
425 }
426
427 void check() {
428 List<int> a = list;
429 int len = a.length;
Jacob Richman4360e992017-03-21 10:07:26 -0700430 if ((a[0] != min) || a[len - 1] != max) Error.error("List is not sorted");
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000431 for (var i = 1; i < len; i++) {
432 if (a[i - 1] > a[i]) Error.error("List is not sorted");
433 }
434 }
435}
436
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000437// B u b b l e S o r t
438class BubbleSort {
439 static void sort(List<int> a) {
440 int len = a.length;
441 for (int i = len - 2; i >= 0; i--) {
442 for (int j = 0; j <= i; j++) {
443 int c = a[j];
444 int n = a[j + 1];
445 if (c > n) {
446 a[j] = n;
447 a[j + 1] = c;
448 }
449 }
450 }
451 }
452}
453
454class BubbleSortBenchmark extends BenchmarkBase {
455 const BubbleSortBenchmark() : super("BubbleSort");
456
457 void warmup() {
458 SortData data = new SortData(30);
459 BubbleSort.sort(data.list);
460 }
461
462 void exercise() {
463 // This value has been copied from benchpress.js, so that we can compare
464 // performance.
465 SortData data = new SortData(130);
466 BubbleSort.sort(data.list);
467 data.check();
468 }
469
470 static void main() {
471 new BubbleSortBenchmark().report();
472 }
473}
474
475// Q u i c k S o r t
476class QuickSort {
477 static void sort(List<int> a, int low, int high) {
478 int pivot = a[(low + high) >> 1];
479 int i = low;
480 int j = high;
481 while (i <= j) {
482 while (a[i] < pivot) i++;
483 while (pivot < a[j]) j--;
484 if (i <= j) {
485 int tmp = a[i];
486 a[i] = a[j];
487 a[j] = tmp;
488 i++;
489 j--;
490 }
491 }
492
493 if (low < j) sort(a, low, j);
494 if (i < high) sort(a, i, high);
495 }
496}
497
498class QuickSortBenchmark extends BenchmarkBase {
499 const QuickSortBenchmark() : super("QuickSort");
500
501 void warmup() {
502 SortData data = new SortData(100);
503 QuickSort.sort(data.list, 0, data.list.length - 1);
504 }
505
506 void exercise() {
507 // This value has been copied from benchpress.js, so that we can compare
508 // performance.
509 SortData data = new SortData(800);
510 QuickSort.sort(data.list, 0, data.list.length - 1);
511 data.check();
512 }
513
514 static void main() {
515 new QuickSortBenchmark().report();
516 }
517}
518
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000519// T r e e S o r t
520class TreeNodePress {
521 int value;
522 TreeNodePress left;
523 TreeNodePress right;
524
525 TreeNodePress(int n) : value = n {}
526
527 void insert(int n) {
528 if (n < value) {
Jacob Richman4360e992017-03-21 10:07:26 -0700529 if (left == null)
530 left = new TreeNodePress(n);
531 else
532 left.insert(n);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000533 } else {
Jacob Richman4360e992017-03-21 10:07:26 -0700534 if (right == null)
535 right = new TreeNodePress(n);
536 else
537 right.insert(n);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000538 }
539 }
540
541 void check() {
542 TreeNodePress left = this.left;
543 TreeNodePress right = this.right;
544 int value = this.value;
545
floitsch@google.com8e6f2382012-11-12 17:19:58 +0000546 return ((left == null) || ((left.value < value) && left.check())) &&
Jacob Richman4360e992017-03-21 10:07:26 -0700547 ((right == null) || ((right.value >= value) && right.check()));
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000548 }
549}
550
551class TreeSort {
552 static void sort(List<int> a) {
553 int len = a.length;
554 TreeNodePress tree = new TreeNodePress(a[0]);
555 for (var i = 1; i < len; i++) tree.insert(a[i]);
556 if (!tree.check()) Error.error("Invalid result, tree not sorted");
557 }
558}
559
560class TreeSortBenchmark extends BenchmarkBase {
561 const TreeSortBenchmark() : super("TreeSort");
562
563 void warmup() {
564 TreeSort.sort(new SortData(100).list);
565 }
566
567 void exercise() {
568 // This value has been copied from benchpress.js, so that we can compare
569 // performance.
570 TreeSort.sort(new SortData(1000).list);
571 }
572}
573
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000574// T a k
575class TakBenchmark extends BenchmarkBase {
576 const TakBenchmark() : super("Tak");
577
578 static void tak(int x, int y, int z) {
579 if (y >= x) return z;
580 return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
581 }
582
583 void warmup() {
584 tak(9, 6, 3);
585 }
586
587 void exercise() {
588 // This value has been copied from benchpress.js, so that we can compare
589 // performance.
590 tak(18, 12, 6);
591 }
592
593 static void main() {
594 new TakBenchmark().report();
595 }
596}
597
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000598// T a k l
599class ListElement {
600 final int length;
601 final ListElement next;
602
603 const ListElement(int length, ListElement next)
Jacob Richman4360e992017-03-21 10:07:26 -0700604 : this.length = length,
605 this.next = next;
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000606
607 static ListElement makeList(int length) {
608 if (length == 0) return null;
609 return new ListElement(length, makeList(length - 1));
610 }
611
612 static bool isShorter(ListElement x, ListElement y) {
613 ListElement xTail = x;
614 ListElement yTail = y;
floitsch@google.com8e6f2382012-11-12 17:19:58 +0000615 while (yTail != null) {
616 if (xTail == null) return true;
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000617 xTail = xTail.next;
618 yTail = yTail.next;
619 }
620 return false;
621 }
622}
623
624class Takl {
625 static ListElement takl(ListElement x, ListElement y, ListElement z) {
626 if (ListElement.isShorter(y, x)) {
Jacob Richman4360e992017-03-21 10:07:26 -0700627 return takl(takl(x.next, y, z), takl(y.next, z, x), takl(z.next, x, y));
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000628 } else {
629 return z;
630 }
631 }
632}
633
634class TaklBenchmark extends BenchmarkBase {
635 const TaklBenchmark() : super("Takl");
636
637 void warmup() {
Jacob Richman4360e992017-03-21 10:07:26 -0700638 Takl.takl(ListElement.makeList(8), ListElement.makeList(4),
639 ListElement.makeList(3));
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000640 }
641
642 void exercise() {
643 // This value has been copied from benchpress.js, so that we can compare
644 // performance.
645 ListElement result = Takl.takl(ListElement.makeList(15),
Jacob Richman4360e992017-03-21 10:07:26 -0700646 ListElement.makeList(10), ListElement.makeList(6));
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000647 if (result.length != 10) {
648 int len = result.length;
649 Error.error("Wrong result: $len should be: 10");
650 }
651 }
652
653 static void main() {
654 new TaklBenchmark().report();
655 }
656}
657
658// M a i n
659
660class BenchPress {
661 static void mainWithArgs(List<String> args) {
662 List<BenchmarkBase> benchmarks = [
Jacob Richman4360e992017-03-21 10:07:26 -0700663 new BubbleSortBenchmark(),
664 new FibBenchmark(),
665 new LoopBenchmark(),
666 new PermuteBenchmark(),
667 new QueensBenchmark(),
668 new QuickSortBenchmark(),
669 new RecurseBenchmark(),
670 new SieveBenchmark(),
671 new SumBenchmark(),
672 new TakBenchmark(),
673 new TaklBenchmark(),
674 new TowersBenchmark(),
675 new TreeSortBenchmark(),
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000676 ];
677 if (args.length > 0) {
678 String benchName = args[0];
679 bool foundBenchmark = false;
680 benchmarks.forEach((bench) {
681 if (bench.name == benchName) {
682 foundBenchmark = true;
683 bench.report();
684 }
685 });
686 if (!foundBenchmark) {
687 Error.error("Benchmark not found: $benchName");
688 }
689 return;
690 }
691 double logMean = 0.0;
692 benchmarks.forEach((bench) {
693 double benchScore = bench.measure();
694 String name = bench.name;
695 print("$name: $benchScore");
696 logMean += Math.log(benchScore);
697 });
698 logMean = logMean / benchmarks.length;
699 double score = Math.pow(Math.E, logMean);
700 print("BenchPress (average): $score");
701 }
702
703 // TODO(floitsch): let main accept arguments from the command line.
704 static void main() {
705 mainWithArgs([]);
706 }
707}
708
709class BenchmarkBase {
710 final String name;
711
712 // Empty constructor.
713 const BenchmarkBase(String name) : this.name = name;
714
715 // The benchmark code.
716 // This function is not used, if both [warmup] and [exercise] are overwritten.
Jacob Richman4360e992017-03-21 10:07:26 -0700717 void run() {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000718
719 // Runs a short version of the benchmark. By default invokes [run] once.
720 void warmup() {
721 run();
722 }
723
Erik Corry029b1cb2017-06-24 13:41:35 +0200724 // Exercises the benchmark. By default invokes [run] 10 times.
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000725 void exercise() {
726 for (int i = 0; i < 10; i++) {
727 run();
728 }
729 }
730
731 // Not measured setup code executed prior to the benchmark runs.
Jacob Richman4360e992017-03-21 10:07:26 -0700732 void setup() {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000733
Erik Corryaa6353b2017-05-01 08:28:01 +0200734 // Not measures teardown code executed after the benchmark runs.
Jacob Richman4360e992017-03-21 10:07:26 -0700735 void teardown() {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000736
737 // Measures the score for this benchmark by executing it repeately until
738 // time minimum has been reached.
739 static double measureFor(Function f, int timeMinimum) {
740 int time = 0;
741 int iter = 0;
floitsch@google.comfb7b9e32013-01-24 12:16:37 +0000742 DateTime start = new DateTime.now();
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000743 while (time < timeMinimum) {
744 f();
floitsch@google.comfb7b9e32013-01-24 12:16:37 +0000745 time = (new DateTime.now().difference(start)).inMilliseconds;
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000746 iter++;
747 }
748 // Force double result by using a double constant.
749 return (1000.0 * iter) / time;
750 }
751
752 // Measures the score for the benchmark and returns it.
753 double measure() {
754 setup();
755 // Warmup for at least 100ms. Discard result.
Jacob Richman4360e992017-03-21 10:07:26 -0700756 measureFor(() {
757 this.warmup();
758 }, -100);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000759 // Run the benchmark for at least 2000ms.
Jacob Richman4360e992017-03-21 10:07:26 -0700760 double result = measureFor(() {
761 this.exercise();
762 }, -2000);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000763 teardown();
764 return result;
765 }
766
767 void report() {
768 double score = measure();
769 print("name: $score");
770 }
Jacob Richman62be0ea2017-03-20 22:19:22 -0700771}
Jacob Richman4360e992017-03-21 10:07:26 -0700772
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000773class Logger {
774 static print(object) {
775 printobject(object);
776 }
Ryan Macnakea4744a02017-03-20 13:42:55 -0700777
Jacob Richman4360e992017-03-21 10:07:26 -0700778 static printobject(obj) {}
779}
Jacob Richman62be0ea2017-03-20 22:19:22 -0700780
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000781//
782// Dromaeo ObjectString
783// Adapted from Mozilla JavaScript performance test suite.
784// Microtests of strings (concatenation, methods).
785
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000786class ObjectString extends BenchmarkBase {
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000787 const ObjectString() : super("Dromaeo.ObjectString");
788
789 static void main() {
790 new ObjectString().report();
791 }
792
793 static void print(String str) {
794 print(str);
795 }
796
797 String getRandomString(int characters) {
798 var result = "";
799 for (var i = 0; i < characters; i++) {
Jacob Richman4360e992017-03-21 10:07:26 -0700800 result +=
801 Strings.createFromCodePoints([(25 * Math.random()).toInt() + 97]);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000802 }
803 result += result;
804 result += result;
805 return result;
806 }
807
808 void run() {
809 //JS Dromeaeo uses 16384
810 final ITERATE1 = 384;
811 //JS Dromeaeo uses 80000
812 final ITERATE2 = 80;
813 //JS Dromeaeo uses 5000
814 final ITERATE3 = 50;
815 //JS Dromeaeo uses 5000
816 final ITERATE4 = 1;
817 //JS Dromaeo uses 5000
818 final ITERATE5 = 1000;
819
820 var result;
821 var text = getRandomString(ITERATE1);
822
823 ConcatStringBenchmark.test(ITERATE2);
824 ConcatStringFromCharCodeBenchmark.test(ITERATE2);
825 StringSplitBenchmark.test(text);
826 StringSplitOnCharBenchmark.test(text);
827 text += text;
828 CharAtBenchmark.test(text, ITERATE3);
829 NumberBenchmark.test(text, ITERATE3);
lrn@google.com3c0ac362013-02-25 10:48:09 +0000830 CodeUnitAtBenchmark.test(text, ITERATE3);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000831 IndexOfBenchmark.test(text, ITERATE3);
832 LastIndexOfBenchmark.test(text, ITERATE3);
833 SliceBenchmark.test(text, ITERATE4);
834 SubstrBenchmark.test(text, ITERATE4);
835 SubstringBenchmark.test(text, ITERATE4);
836 ToLowerCaseBenchmark.test(text, ITERATE5);
837 ToUpperCaseBenchmark.test(text, ITERATE5);
838 ComparingBenchmark.test(text, ITERATE5);
839 }
840}
841
842class ConcatStringBenchmark {
843 ConcatStringBenchmark() {}
844
845 static String test(var iterations) {
846 var str = "";
847 for (var i = 0; i < iterations; i++) {
848 str += "a";
849 }
850 return str;
851 }
852}
853
854class ConcatStringFromCharCodeBenchmark {
855 ConcatStringFromCharCodeBenchmark() {}
856
857 static String test(var iterations) {
858 var str = "";
859 for (var i = 0; i < (iterations / 2); i++) {
860 str += Strings.createFromCodePoints([97]);
861 }
862 return str;
863 }
864}
865
866class StringSplitBenchmark {
867 StringSplitBenchmark() {}
868
869 static List<String> test(String input) {
870 return input.split("");
871 }
872}
873
874class StringSplitOnCharBenchmark {
875 StringSplitOnCharBenchmark() {}
876
877 static List<String> test(String input) {
878 String multiple = input;
879 multiple += multiple;
880 multiple += multiple;
881 multiple += multiple;
882 multiple += multiple;
883 return multiple.split("a");
884 }
885}
886
887class CharAtBenchmark {
888 CharAtBenchmark() {}
889
890 static String test(String input, var iterations) {
891 var str;
892 for (var j = 0; j < iterations; j++) {
893 str = input[0];
894 str = input[input.length - 1];
895 str = input[150]; //set it to 15000
896 str = input[120]; //set it to 12000
897 }
898 return str;
899 }
900}
901
902class NumberBenchmark {
903 NumberBenchmark() {}
904
905 static String test(String input, var iterations) {
906 var str;
907 for (var j = 0; j < iterations; j++) {
908 str = input[0];
909 str = input[input.length - 1];
910 str = input[150]; //set it to 15000
911 str = input[100]; //set it to 10000
912 str = input[50]; //set it to 5000
913 }
914 return str;
915 }
916}
917
lrn@google.com3c0ac362013-02-25 10:48:09 +0000918class CodeUnitAtBenchmark {
919 CodeUnitAtBenchmark() {}
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000920
921 static String test(String input, var iterations) {
922 var str;
923 for (var j = 0; j < iterations; j++) {
lrn@google.com3c0ac362013-02-25 10:48:09 +0000924 str = input.codeUnitAt(0);
925 str = input.codeUnitAt(input.length - 1);
926 str = input.codeUnitAt(150); //set it to 15000
927 str = input.codeUnitAt(100); //set it to 10000
928 str = input.codeUnitAt(50); //set it to 5000
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000929 }
930 return str;
931 }
932}
933
934class IndexOfBenchmark {
935 IndexOfBenchmark() {}
936
937 static String test(String input, var iterations) {
938 var str;
939 for (var j = 0; j < iterations; j++) {
940 str = input.indexOf("a", 0);
941 str = input.indexOf("b", 0);
942 str = input.indexOf("c", 0);
943 str = input.indexOf("d", 0);
944 }
945 return str;
946 }
947}
948
949class LastIndexOfBenchmark {
950 LastIndexOfBenchmark() {}
951
952 static String test(String input, var iterations) {
953 var str;
954 for (var j = 0; j < iterations; j++) {
955 str = input.lastIndexOf("a", input.length - 1);
956 str = input.lastIndexOf("b", input.length - 1);
957 str = input.lastIndexOf("c", input.length - 1);
958 str = input.lastIndexOf("d", input.length - 1);
959 }
960 return str;
961 }
962}
963
964class SliceBenchmark {
965 SliceBenchmark() {}
966
967 static String test(String input, var iterations) {
968 var str;
969 for (var j = 0; j < iterations; j++) {
970 str = input.substring(0, input.length - 1);
971 str = input.substring(0, 5);
972 str = input.substring(input.length - 1, input.length - 1);
973 str = input.substring(input.length - 6, input.length - 1);
974 str = input.substring(150, 155); //set to 15000 and 15005
Jacob Richman4360e992017-03-21 10:07:26 -0700975 str = input.substring(120, input.length - 1); //set to 12000
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000976 }
977 return str;
978 }
979}
980
981class SubstrBenchmark {
982 SubstrBenchmark() {}
983
984 static String test(String input, var iterations) {
985 var str;
986 for (var j = 0; j < iterations; j++) {
Jacob Richman4360e992017-03-21 10:07:26 -0700987 str = input.substring(0, input.length - 1);
dgrove@google.com4c0f5592011-10-05 05:20:07 +0000988 str = input.substring(0, 4);
989 str = input.substring(input.length - 1, input.length - 1);
990 str = input.substring(input.length - 6, input.length - 6);
991 str = input.substring(150, 154); //set to 15000 and 15005
992 str = input.substring(120, 124); //set to 12000
993 }
994 return str;
995 }
996}
997
998class SubstringBenchmark {
999 SubstringBenchmark() {}
1000
1001 static String test(String input, var iterations) {
1002 var str;
1003 for (var j = 0; j < iterations; j++) {
1004 str = input.substring(0, input.length - 1);
1005 str = input.substring(0, 4);
1006 str = input.substring(input.length - 1, input.length - 1);
1007 str = input.substring(input.length - 6, input.length - 2);
1008 str = input.substring(150, 154); //set to 15000 and 15005
1009 str = input.substring(120, input.length - 2); //set to 12000
1010 }
1011 return str;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001012 }
1013}
1014
1015class ToLowerCaseBenchmark {
1016 ToLowerCaseBenchmark() {}
1017
1018 static String test(String input, var iterations) {
1019 var str;
1020 for (var j = 0; j < (iterations / 1000); j++) {
1021 str = Ascii.toLowerCase(input);
1022 }
1023 return str;
1024 }
1025}
1026
1027class ToUpperCaseBenchmark {
1028 ToUpperCaseBenchmark() {}
1029
1030 static String test(String input, var iterations) {
1031 var str;
1032 for (var j = 0; j < (iterations / 1000); j++) {
1033 str = Ascii.toUpperCase(input);
1034 }
1035 return str;
1036 }
1037}
1038
1039class ComparingBenchmark {
1040 ComparingBenchmark() {}
1041
1042 static bool test(String input, var iterations) {
1043 var tmp = "a${input}a";
1044 var tmp2 = "a${input}a";
1045 var res;
1046 for (var j = 0; j < (iterations / 1000); j++) {
1047 res = (tmp.compareTo(tmp2) == 0);
1048 res = (tmp.compareTo(tmp2) < 0);
1049 res = (tmp.compareTo(tmp2) > 0);
1050 }
1051 return res;
1052 }
1053}
1054
1055// Benchmarks basic message communication between two isolates.
1056
1057class Benchmark1 {
iposva@google.com327ff5d2012-08-27 23:51:37 +00001058 static const MESSAGES = 10000;
1059 static const INIT_MESSAGE = 0;
1060 static const TERMINATION_MESSAGE = -1;
1061 static const WARMUP_TIME = 1000;
1062 static const RUN_TIME = 1000;
1063 static const RUNS = 5;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001064
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001065 static int run() {
1066 return _run;
1067 }
1068
1069 static void add_result(var opsms) {
1070 _run++;
1071 _opsms += opsms;
1072 }
1073
1074 static void get_result() {
1075 return _opsms / _run;
1076 }
1077
1078 static void init() {
1079 _run = 0;
1080 _opsms = 0.0;
1081 }
1082
1083 static void main() {
1084 init();
hausner@google.com77614b72012-10-17 20:39:42 +00001085 PingPongGame pingPongGame = new PingPongGame();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001086 }
1087
1088 static var _run;
1089 static var _opsms;
1090}
1091
1092class PingPongGame {
hausner@google.com77614b72012-10-17 20:39:42 +00001093 PingPongGame()
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001094 : _ping = new ReceivePort(),
1095 _pingPort = _ping.toSendPort(),
1096 _pong = null,
1097 _warmedup = false,
1098 _iterations = 0 {
ager@google.com4531c0c2012-08-03 07:24:29 +00001099 SendPort _pong = spawnFunction(pong);
1100 play();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001101 }
1102
1103 void startRound() {
1104 _iterations++;
1105 _pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
1106 }
1107
1108 void evaluateRound() {
floitsch@google.comfb7b9e32013-01-24 12:16:37 +00001109 int time = (new DateTime.now().difference(_start)).inMilliseconds;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001110 if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
1111 startRound();
1112 } else if (!_warmedup) {
1113 _warmedup = true;
floitsch@google.comfb7b9e32013-01-24 12:16:37 +00001114 _start = new DateTime.now();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001115 _iterations = 0;
1116 startRound();
1117 } else if (_warmedup && time < Benchmark1.RUN_TIME) {
1118 startRound();
1119 } else {
1120 shutdown();
1121 Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
1122 if (Benchmark1.run() < Benchmark1.RUNS) {
hausner@google.com77614b72012-10-17 20:39:42 +00001123 new PingPongGame();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001124 } else {
1125 print("PingPong: ", Benchmark1.get_result());
1126 }
1127 }
1128 }
1129
1130 void play() {
1131 _ping.receive((int message, SendPort replyTo) {
1132 if (message < Benchmark1.MESSAGES) {
1133 _pong.send(++message, null);
1134 } else {
1135 evaluateRound();
1136 }
1137 });
floitsch@google.comfb7b9e32013-01-24 12:16:37 +00001138 _start = new DateTime.now();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001139 startRound();
1140 }
1141
1142 void shutdown() {
1143 _pong.send(Benchmark1.TERMINATION_MESSAGE, null);
1144 _ping.close();
1145 }
1146
floitsch@google.comfb7b9e32013-01-24 12:16:37 +00001147 DateTime _start;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001148 SendPort _pong;
1149 SendPort _pingPort;
1150 ReceivePort _ping;
1151 bool _warmedup;
1152 int _iterations;
1153}
1154
ager@google.com4531c0c2012-08-03 07:24:29 +00001155void pong() {
1156 port.receive((message, SendPort replyTo) {
1157 if (message == Benchmark1.INIT_MESSAGE) {
1158 replyTo.send(message, null);
1159 } else if (message == Benchmark1.TERMINATION_MESSAGE) {
1160 port.close();
1161 } else {
1162 replyTo.send(message, null);
1163 }
1164 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001165}
1166
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001167class ManyGenericInstanceofTest {
1168 static testMain() {
1169 for (int i = 0; i < 5000; i++) {
1170 GenericInstanceof.testMain();
1171 }
1172 }
1173}
1174
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001175// ---------------------------------------------------------------------------
1176// THE REST OF THIS FILE COULD BE AUTOGENERATED
1177// ---------------------------------------------------------------------------
1178
ager@google.com4531c0c2012-08-03 07:24:29 +00001179// ---------------------------------------------------------------------------
1180// tests/isolate/spawn_test.dart
1181// ---------------------------------------------------------------------------
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001182
ager@google.com4531c0c2012-08-03 07:24:29 +00001183spawn_test_main() {
1184 test("spawn a new isolate", () {
1185 SendPort port = spawnFunction(entry);
1186 port.call(42).then(expectAsync1((message) {
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001187 Expect.equals(42, message);
ager@google.com4531c0c2012-08-03 07:24:29 +00001188 }));
1189 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001190}
1191
ager@google.com4531c0c2012-08-03 07:24:29 +00001192void entry() {
1193 port.receive((message, SendPort replyTo) {
1194 Expect.equals(42, message);
1195 replyTo.send(42, null);
1196 port.close();
1197 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001198}
1199
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001200// ---------------------------------------------------------------------------
ager@google.com4531c0c2012-08-03 07:24:29 +00001201// tests/isolate/isolate_negative_test.dart
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001202// ---------------------------------------------------------------------------
1203
ager@google.com4531c0c2012-08-03 07:24:29 +00001204void isolate_negative_entry() {
1205 port.receive((ignored, replyTo) {
1206 replyTo.send("foo", null);
1207 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001208}
1209
ager@google.com4531c0c2012-08-03 07:24:29 +00001210isolate_negative_test_main() {
1211 test("ensure isolate code is executed", () {
1212 SendPort port = spawnFunction(isolate_negative_entry);
1213 port.call("foo").then(expectAsync1((message) {
Jacob Richman4360e992017-03-21 10:07:26 -07001214 Expect.equals(true, "Expected fail"); // <=-------- Should fail here.
ager@google.com4531c0c2012-08-03 07:24:29 +00001215 }));
1216 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001217}
1218
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001219// ---------------------------------------------------------------------------
ager@google.com4531c0c2012-08-03 07:24:29 +00001220// tests/isolate/message_test.dart
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001221// ---------------------------------------------------------------------------
1222
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001223// ---------------------------------------------------------------------------
1224// Message passing test.
1225// ---------------------------------------------------------------------------
1226
1227class MessageTest {
iposva@google.com327ff5d2012-08-27 23:51:37 +00001228 static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
1229 static const List list2 = const [null, list1, list1, list1, list1];
1230 static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
1231 static const Map map1 = const {
Jacob Richman4360e992017-03-21 10:07:26 -07001232 "a=1": 1,
1233 "b=2": 2,
1234 "c=3": 3,
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001235 };
iposva@google.com327ff5d2012-08-27 23:51:37 +00001236 static const Map map2 = const {
Jacob Richman4360e992017-03-21 10:07:26 -07001237 "list1": list1,
1238 "list2": list2,
1239 "list3": list3,
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001240 };
iposva@google.com327ff5d2012-08-27 23:51:37 +00001241 static const List list4 = const [map1, map2];
1242 static const List elms = const [
Jacob Richman4360e992017-03-21 10:07:26 -07001243 list1,
1244 list2,
1245 list3,
1246 list4,
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001247 ];
1248
1249 static void VerifyMap(Map expected, Map actual) {
1250 Expect.equals(true, expected is Map);
1251 Expect.equals(true, actual is Map);
1252 Expect.equals(expected.length, actual.length);
1253 testForEachMap(key, value) {
1254 if (value is List) {
1255 VerifyList(value, actual[key]);
1256 } else {
1257 Expect.equals(value, actual[key]);
1258 }
1259 }
Jacob Richman4360e992017-03-21 10:07:26 -07001260
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001261 expected.forEach(testForEachMap);
1262 }
1263
1264 static void VerifyList(List expected, List actual) {
1265 for (int i = 0; i < expected.length; i++) {
1266 if (expected[i] is List) {
1267 VerifyList(expected[i], actual[i]);
1268 } else if (expected[i] is Map) {
1269 VerifyMap(expected[i], actual[i]);
1270 } else {
1271 Expect.equals(expected[i], actual[i]);
1272 }
1273 }
1274 }
1275
1276 static void VerifyObject(int index, var actual) {
1277 var expected = elms[index];
1278 Expect.equals(true, expected is List);
1279 Expect.equals(true, actual is List);
1280 Expect.equals(expected.length, actual.length);
1281 VerifyList(expected, actual);
1282 }
1283}
1284
ager@google.com4531c0c2012-08-03 07:24:29 +00001285pingPong() {
1286 int count = 0;
1287 port.receive((var message, SendPort replyTo) {
1288 if (message == -1) {
1289 port.close();
1290 replyTo.send(count, null);
1291 } else {
1292 // Check if the received object is correct.
1293 if (count < MessageTest.elms.length) {
1294 MessageTest.VerifyObject(count, message);
1295 }
1296 // Bounce the received object back so that the sender
1297 // can make sure that the object matches.
1298 replyTo.send(message, null);
1299 count++;
1300 }
1301 });
1302}
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001303
ager@google.com4531c0c2012-08-03 07:24:29 +00001304message_test_main() {
1305 test("send objects and receive them back", () {
1306 SendPort remote = spawnFunction(pingPong);
1307 // Send objects and receive them back.
1308 for (int i = 0; i < MessageTest.elms.length; i++) {
1309 var sentObject = MessageTest.elms[i];
ager@google.com4531c0c2012-08-03 07:24:29 +00001310 remote.call(sentObject).then(expectAsync1((var receivedObject) {
Siva Annamalai46daa582016-02-08 10:47:30 -08001311 MessageTest.VerifyObject(i, receivedObject);
ager@google.com4531c0c2012-08-03 07:24:29 +00001312 }));
1313 }
1314
1315 // Send recursive objects and receive them back.
1316 List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
Jacob Richman4360e992017-03-21 10:07:26 -07001317 List local_list2 = [null, local_list1, local_list1];
ager@google.com4531c0c2012-08-03 07:24:29 +00001318 List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +00001319 List sendObject = new List(5);
ager@google.com4531c0c2012-08-03 07:24:29 +00001320 sendObject[0] = local_list1;
1321 sendObject[1] = sendObject;
1322 sendObject[2] = local_list2;
1323 sendObject[3] = sendObject;
1324 sendObject[4] = local_list3;
1325 remote.call(sendObject).then((var replyObject) {
1326 Expect.equals(true, sendObject is List);
1327 Expect.equals(true, replyObject is List);
1328 Expect.equals(sendObject.length, replyObject.length);
floitsch@google.com8e6f2382012-11-12 17:19:58 +00001329 Expect.equals(true, identical(replyObject[1], replyObject));
1330 Expect.equals(true, identical(replyObject[3], replyObject));
1331 Expect.equals(true, identical(replyObject[0], replyObject[2][1]));
1332 Expect.equals(true, identical(replyObject[0], replyObject[2][2]));
1333 Expect.equals(true, identical(replyObject[2], replyObject[4][0]));
1334 Expect.equals(true, identical(replyObject[0][0], replyObject[0][2]));
Alexander Markovc3b59392018-06-04 20:10:40 +00001335 // TODO(alexmarkov): Revise this comment.
ager@google.com4531c0c2012-08-03 07:24:29 +00001336 // Bigint literals are not canonicalized so do a == check.
1337 Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
1338 });
1339
1340 // Shutdown the MessageServer.
1341 remote.call(-1).then(expectAsync1((int message) {
Jacob Richman4360e992017-03-21 10:07:26 -07001342 Expect.equals(MessageTest.elms.length + 1, message);
1343 }));
ager@google.com4531c0c2012-08-03 07:24:29 +00001344 });
1345}
1346
1347// ---------------------------------------------------------------------------
1348// tests/isolate/request_reply_test.dart
1349// ---------------------------------------------------------------------------
1350
1351void request_reply_entry() {
1352 port.receive((message, SendPort replyTo) {
1353 replyTo.send(message + 87);
1354 port.close();
1355 });
1356}
1357
1358void request_reply_main() {
1359 test("call", () {
1360 SendPort port = spawnFunction(request_reply_entry);
1361 port.call(42).then(expectAsync1((message) {
1362 Expect.equals(42 + 87, message);
1363 }));
1364 });
1365
1366 test("send", () {
1367 SendPort port = spawnFunction(request_reply_entry);
1368 ReceivePort reply = new ReceivePort();
1369 port.send(99, reply.toSendPort());
1370 reply.receive(expectAsync2((message, replyTo) {
1371 Expect.equals(99 + 87, message);
1372 reply.close();
1373 }));
1374 });
1375}
1376
1377// ---------------------------------------------------------------------------
1378// tests/isolate/count_test.dart
1379// ---------------------------------------------------------------------------
1380
1381void countMessages() {
1382 int count = 0;
1383 port.receive((int message, SendPort replyTo) {
1384 if (message == -1) {
1385 Expect.equals(10, count);
1386 replyTo.send(-1, null);
1387 port.close();
1388 return;
1389 }
1390 Expect.equals(count, message);
1391 count++;
1392 replyTo.send(message * 2, null);
1393 });
1394}
1395
1396void count_main() {
1397 test("count 10 consecutive messages", () {
1398 int count = 0;
1399 SendPort remote = spawnFunction(countMessages);
1400 ReceivePort local = new ReceivePort();
1401 SendPort reply = local.toSendPort();
1402
1403 local.receive(expectAsync2((int message, SendPort replyTo) {
1404 if (message == -1) {
1405 Expect.equals(11, count);
1406 local.close();
1407 return;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001408 }
1409
ager@google.com4531c0c2012-08-03 07:24:29 +00001410 Expect.equals((count - 1) * 2, message);
1411 remote.send(count++, reply);
1412 if (count == 10) {
1413 remote.send(-1, reply);
1414 }
regis@google.comadb53462012-10-16 16:03:47 +00001415 }, 11));
ager@google.com4531c0c2012-08-03 07:24:29 +00001416 remote.send(count++, reply);
1417 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001418}
1419
ager@google.com4531c0c2012-08-03 07:24:29 +00001420// ---------------------------------------------------------------------------
1421// tests/isolate/mandel_isolate_test.dart
1422// ---------------------------------------------------------------------------
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001423
iposva@google.com327ff5d2012-08-27 23:51:37 +00001424const TERMINATION_MESSAGE = -1;
1425const N = 100;
1426const ISOLATES = 20;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001427
ager@google.com4531c0c2012-08-03 07:24:29 +00001428mandel_main() {
1429 test("Render Mandelbrot in parallel", () {
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001430 final state = new MandelbrotState();
ager@google.com4531c0c2012-08-03 07:24:29 +00001431 state._validated.future.then(expectAsync1((result) {
1432 expect(result, isTrue);
1433 }));
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001434 for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
ager@google.com4531c0c2012-08-03 07:24:29 +00001435 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001436}
1437
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001438class MandelbrotState {
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001439 MandelbrotState() {
ager@google.com4531c0c2012-08-03 07:24:29 +00001440 _result = new List<List<int>>(N);
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +00001441 _lineProcessedBy = new List<LineProcessorClient>(N);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001442 _sent = 0;
ager@google.com4531c0c2012-08-03 07:24:29 +00001443 _missing = N;
1444 _validated = new Completer<bool>();
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001445 }
1446
1447 void startClient(int id) {
ager@google.com4531c0c2012-08-03 07:24:29 +00001448 assert(_sent < N);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001449 final client = new LineProcessorClient(this, id);
1450 client.processLine(_sent++);
1451 }
1452
1453 void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
floitsch@google.com8e6f2382012-11-12 17:19:58 +00001454 assert(_result[y] == null);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001455 _result[y] = line;
1456 _lineProcessedBy[y] = client;
1457
ager@google.com4531c0c2012-08-03 07:24:29 +00001458 if (_sent != N) {
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001459 client.processLine(_sent++);
1460 } else {
1461 client.shutdown();
1462 }
1463
1464 // If all lines have been computed, validate the result.
ager@google.com4531c0c2012-08-03 07:24:29 +00001465 if (--_missing == 0) {
1466 _printResult();
1467 _validateResult();
1468 }
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001469 }
1470
1471 void _validateResult() {
1472 // TODO(ngeoffray): Implement this.
ager@google.com4531c0c2012-08-03 07:24:29 +00001473 _validated.complete(true);
1474 }
1475
1476 void _printResult() {
1477 var output = new StringBuffer();
1478 for (int i = 0; i < _result.length; i++) {
1479 List<int> line = _result[i];
1480 for (int j = 0; j < line.length; j++) {
floitsch@google.comdd48256f2013-03-08 13:07:18 +00001481 if (line[j] < 10) output.write("0");
1482 output.write(line[j]);
ager@google.com4531c0c2012-08-03 07:24:29 +00001483 }
floitsch@google.comdd48256f2013-03-08 13:07:18 +00001484 output.write("\n");
ager@google.com4531c0c2012-08-03 07:24:29 +00001485 }
1486 // print(output);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001487 }
1488
1489 List<List<int>> _result;
1490 List<LineProcessorClient> _lineProcessedBy;
1491 int _sent;
1492 int _missing;
ager@google.com4531c0c2012-08-03 07:24:29 +00001493 Completer<bool> _validated;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001494}
1495
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001496class LineProcessorClient {
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001497 LineProcessorClient(MandelbrotState this._state, int this._id) {
ager@google.com4531c0c2012-08-03 07:24:29 +00001498 _port = spawnFunction(processLines);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001499 }
1500
1501 void processLine(int y) {
ager@google.com4531c0c2012-08-03 07:24:29 +00001502 _port.call(y).then((List<int> message) {
1503 _state.notifyProcessedLine(this, y, message);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001504 });
1505 }
1506
1507 void shutdown() {
ager@google.com4531c0c2012-08-03 07:24:29 +00001508 _port.send(TERMINATION_MESSAGE, null);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001509 }
1510
1511 MandelbrotState _state;
1512 int _id;
ager@google.com4531c0c2012-08-03 07:24:29 +00001513 SendPort _port;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001514}
1515
ager@google.com4531c0c2012-08-03 07:24:29 +00001516List<int> processLine(int y) {
1517 double inverseN = 2.0 / N;
1518 double Civ = y * inverseN - 1.0;
lrn@google.com6b4f4b1b2013-02-27 08:45:04 +00001519 List<int> result = new List<int>(N);
ager@google.com4531c0c2012-08-03 07:24:29 +00001520 for (int x = 0; x < N; x++) {
1521 double Crv = x * inverseN - 1.5;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001522
ager@google.com4531c0c2012-08-03 07:24:29 +00001523 double Zrv = Crv;
1524 double Ziv = Civ;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001525
ager@google.com4531c0c2012-08-03 07:24:29 +00001526 double Trv = Crv * Crv;
1527 double Tiv = Civ * Civ;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001528
ager@google.com4531c0c2012-08-03 07:24:29 +00001529 int i = 49;
1530 do {
1531 Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
1532 Zrv = Trv - Tiv + Crv;
1533
1534 Trv = Zrv * Zrv;
1535 Tiv = Ziv * Ziv;
1536 } while (((Trv + Tiv) <= 4.0) && (--i > 0));
1537
1538 result[x] = i;
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001539 }
ager@google.com4531c0c2012-08-03 07:24:29 +00001540 return result;
1541}
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001542
ager@google.com4531c0c2012-08-03 07:24:29 +00001543void processLines() {
1544 port.receive((message, SendPort replyTo) {
1545 if (message == TERMINATION_MESSAGE) {
1546 assert(replyTo == null);
1547 port.close();
1548 } else {
1549 replyTo.send(processLine(message), null);
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001550 }
ager@google.com4531c0c2012-08-03 07:24:29 +00001551 });
dgrove@google.com4c0f5592011-10-05 05:20:07 +00001552}