blob: 5457ef54201368ee810d0990886cf60eeef67491 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:isolate';
import 'dart:async';
class Expect {
static void equals(x, y) {
if (x != y) throw new ArgumentError('not equal');
}
}
class Fields {
Fields(int i, int j) : fld1 = i, fld2 = j, fld5 = true {}
int fld1;
final int fld2;
static int fld3;
static const int fld4 = 10;
bool fld5;
}
class FieldsTest {
static Fields testMain() {
Fields obj = new Fields(10, 20);
Expect.equals(10, obj.fld1);
Expect.equals(20, obj.fld2);
Expect.equals(10, Fields.fld4);
Expect.equals(true, obj.fld5);
return obj;
}
}
// Benchpress: A collection of micro-benchmarks.
// Ported from internal v8 benchmark suite.
class Error {
static void error(String msg) {
throw msg;
}
}
// F i b o n a c c i
class Fibonacci {
static int fib(int n) {
if (n <= 1) return 1;
return fib(n - 1) + fib(n - 2);
}
}
class FibBenchmark extends BenchmarkBase {
const FibBenchmark() : super("Fibonacci");
void warmup() {
Fibonacci.fib(10);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var result = Fibonacci.fib(20);
if (result != 10946)
Error.error("Wrong result: $result. Should be: 10946.");
}
static void main() {
new FibBenchmark().report();
}
}
// L o o p
class Loop {
static int loop(int outerIterations) {
int sum = 0;
for (int i = 0; i < outerIterations; i++) {
for (int j = 0; j < 100; j++) {
sum++;
}
}
return sum;
}
}
class LoopBenchmark extends BenchmarkBase {
const LoopBenchmark() : super("Loop");
void warmup() {
Loop.loop(10);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var result = Loop.loop(200);
if (result != 20000)
Error.error("Wrong result: $result. Should be: 20000");
}
static void main() {
new LoopBenchmark().report();
}
}
// T o w e r s
class TowersDisk {
final int size;
TowersDisk next;
TowersDisk(size) : this.size = size, next = null {}
}
class Towers {
List<TowersDisk> piles;
int movesDone;
Towers(int disks)
: piles = new List<TowersDisk>(3), movesDone = 0 {
build(0, disks);
}
void build(int pile, int disks) {
for (var i = disks - 1; i >= 0; i--) {
push(pile, new TowersDisk(i));
}
}
void push(int pile, TowersDisk disk) {
TowersDisk top = piles[pile];
if ((top != null) && (disk.size >= top.size))
Error.error("Cannot put a big disk on a smaller disk.");
disk.next = top;
piles[pile] = disk;
}
TowersDisk pop(int pile) {
var top = piles[pile];
if (top == null)
Error.error("Attempting to remove a disk from an empty pile.");
piles[pile] = top.next;
top.next = null;
return top;
}
void moveTop(int from, int to) {
push(to, pop(from));
movesDone++;
}
void move(int from, int to, int disks) {
if (disks == 1) {
moveTop(from, to);
} else {
int other = 3 - from - to;
move(from, other, disks - 1);
moveTop(from, to);
move(other, to, disks - 1);
}
}
}
class TowersBenchmark extends BenchmarkBase {
const TowersBenchmark() : super("Towers");
void warmup() {
new Towers(6).move(0, 1, 6);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
var towers = new Towers(13);
towers.move(0, 1, 13);
if (towers.movesDone != 8191) {
var moves = towers.movesDone;
Error.error("Error in result: $moves should be: 8191");
}
}
static void main() {
new TowersBenchmark().report();
}
}
// S i e v e
class SieveBenchmark extends BenchmarkBase {
const SieveBenchmark() : super("Sieve");
static int sieve(int size) {
int primeCount = 0;
List<bool> flags = new List<bool>(size + 1);
for (int i = 1; i < size; i++) flags[i] = true;
for (int i = 2; i < size; i++) {
if (flags[i]) {
primeCount++;
for (int k = i + 1; k <= size; k += i)
flags[k - 1] = false;
}
}
return primeCount;
}
void warmup() {
sieve(100);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = sieve(1000);
if (result != 168)
Error.error("Wrong result: $result should be: 168");
}
static void main() {
new SieveBenchmark().report();
}
}
// P e r m u t e
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Permute {
int permuteCount;
Permute() {}
void swap(int n, int k, List<int> list) {
int tmp = list[n];
list[n] = list[k];
list[k] = tmp;
}
void doPermute(int n, List<int> list) {
permuteCount++;
if (n != 1) {
doPermute(n - 1, list);
for (int k = n - 1; k >= 1; k--) {
swap(n, k, list);
doPermute(n - 1, list);
swap(n, k, list);
}
}
}
int permute(int size) {
permuteCount = 0;
List<int> list = new List<int>(size);
for (int i = 1; i < size; i++) list[i] = i - 1;
doPermute(size - 1, list);
return permuteCount;
}
}
class PermuteBenchmark extends BenchmarkBase {
const PermuteBenchmark() : super("Permute");
void warmup() {
new Permute().permute(4);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = new Permute().permute(8);
if (result != 8660)
Error.error("Wrong result: $result should be: 8660");
}
static void main() {
new PermuteBenchmark().report();
}
}
// Q u e e n s
// The original benchmark uses one-based indexing. Even though arrays in JS and
// lists in dart are zero-based, we stay with one-based indexing
// (wasting one element).
class Queens {
static bool tryQueens(int i,
List<bool> a,
List<bool> b,
List<bool> c,
List<int> x) {
int j = 0;
bool q = false;
while ((!q) && (j != 8)) {
j++;
q = false;
if (b[j] && a[i + j] && c[i - j + 7]) {
x[i] = j;
b[j] = false;
a[i + j] = false;
c[i - j + 7] = false;
if (i < 8) {
q = tryQueens(i + 1, a, b, c, x);
if (!q) {
b[j] = true;
a[i + j] = true;
c[i - j + 7] = true;
}
} else {
q = true;
}
}
}
return q;
}
static void queens() {
List<bool> a = new List<bool>(9);
List<bool> b = new List<bool>(17);
List<bool> c = new List<bool>(15);
List<int> x = new List<int>(9);
b[1] = false;
for (int i = -7; i <= 16; i++) {
if ((i >= 1) && (i <= 8)) a[i] = true;
if (i >= 2) b[i] = true;
if (i <= 7) c[i + 7] = true;
}
if (!tryQueens(1, b, a, c, x))
Error.error("Error in queens");
}
}
class QueensBenchmark extends BenchmarkBase {
const QueensBenchmark() : super("Queens");
void warmup() {
Queens.queens();
}
void exercise() {
Queens.queens();
}
static void main() {
new QueensBenchmark().report();
}
}
// R e c u r s e
class Recurse {
static int recurse(int n) {
if (n <= 0) return 1;
recurse(n - 1);
return recurse(n - 1);
}
}
class RecurseBenchmark extends BenchmarkBase {
const RecurseBenchmark() : super("Recurse");
void warmup() {
Recurse.recurse(7);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
Recurse.recurse(13);
}
static void main() {
new RecurseBenchmark().report();
}
}
// S u m
class SumBenchmark extends BenchmarkBase {
const SumBenchmark() : super("Sum");
static int sum(int start, int end) {
var sum = 0;
for (var i = start; i <= end; i++) sum += i;
return sum;
}
void warmup() {
sum(1, 1000);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
int result = sum(1, 10000);
if (result != 50005000)
Error.error("Wrong result: $result should be 50005000");
}
static void main() {
new SumBenchmark().report();
}
}
// H e l p e r f u n c t i o n s f o r s o r t s
class Random {
static const int INITIAL_SEED = 74755;
int seed;
Random() : seed = INITIAL_SEED {}
int random() {
seed = ((seed * 1309) + 13849) % 65536;
return seed;
}
}
//
class SortData {
List<int> list;
int min;
int max;
SortData(int length) {
Random r = new Random();
list = new List<int>(length);
for (int i = 0; i < length; i++) list[i] = r.random();
int min, max;
min = max = list[0];
for (int i = 0; i < length; i++) {
int e = list[i];
if (e > max) max = e;
if (e < min) min = e;
}
this.min = min;
this.max = max;
}
void check() {
List<int> a = list;
int len = a.length;
if ((a[0] != min) || a[len - 1] != max)
Error.error("List is not sorted");
for (var i = 1; i < len; i++) {
if (a[i - 1] > a[i]) Error.error("List is not sorted");
}
}
}
// B u b b l e S o r t
class BubbleSort {
static void sort(List<int> a) {
int len = a.length;
for (int i = len - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
int c = a[j];
int n = a[j + 1];
if (c > n) {
a[j] = n;
a[j + 1] = c;
}
}
}
}
}
class BubbleSortBenchmark extends BenchmarkBase {
const BubbleSortBenchmark() : super("BubbleSort");
void warmup() {
SortData data = new SortData(30);
BubbleSort.sort(data.list);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
SortData data = new SortData(130);
BubbleSort.sort(data.list);
data.check();
}
static void main() {
new BubbleSortBenchmark().report();
}
}
// Q u i c k S o r t
class QuickSort {
static void sort(List<int> a, int low, int high) {
int pivot = a[(low + high) >> 1];
int i = low;
int j = high;
while (i <= j) {
while (a[i] < pivot) i++;
while (pivot < a[j]) j--;
if (i <= j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
}
if (low < j) sort(a, low, j);
if (i < high) sort(a, i, high);
}
}
class QuickSortBenchmark extends BenchmarkBase {
const QuickSortBenchmark() : super("QuickSort");
void warmup() {
SortData data = new SortData(100);
QuickSort.sort(data.list, 0, data.list.length - 1);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
SortData data = new SortData(800);
QuickSort.sort(data.list, 0, data.list.length - 1);
data.check();
}
static void main() {
new QuickSortBenchmark().report();
}
}
// T r e e S o r t
class TreeNodePress {
int value;
TreeNodePress left;
TreeNodePress right;
TreeNodePress(int n) : value = n {}
void insert(int n) {
if (n < value) {
if (left == null) left = new TreeNodePress(n);
else left.insert(n);
} else {
if (right == null) right = new TreeNodePress(n);
else right.insert(n);
}
}
void check() {
TreeNodePress left = this.left;
TreeNodePress right = this.right;
int value = this.value;
return ((left == null) || ((left.value < value) && left.check())) &&
((right == null) || ((right.value >= value) && right.check()));
}
}
class TreeSort {
static void sort(List<int> a) {
int len = a.length;
TreeNodePress tree = new TreeNodePress(a[0]);
for (var i = 1; i < len; i++) tree.insert(a[i]);
if (!tree.check()) Error.error("Invalid result, tree not sorted");
}
}
class TreeSortBenchmark extends BenchmarkBase {
const TreeSortBenchmark() : super("TreeSort");
void warmup() {
TreeSort.sort(new SortData(100).list);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
TreeSort.sort(new SortData(1000).list);
}
}
// T a k
class TakBenchmark extends BenchmarkBase {
const TakBenchmark() : super("Tak");
static void tak(int x, int y, int z) {
if (y >= x) return z;
return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
}
void warmup() {
tak(9, 6, 3);
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
tak(18, 12, 6);
}
static void main() {
new TakBenchmark().report();
}
}
// T a k l
class ListElement {
final int length;
final ListElement next;
const ListElement(int length, ListElement next)
: this.length = length,
this.next = next;
static ListElement makeList(int length) {
if (length == 0) return null;
return new ListElement(length, makeList(length - 1));
}
static bool isShorter(ListElement x, ListElement y) {
ListElement xTail = x;
ListElement yTail = y;
while (yTail != null) {
if (xTail == null) return true;
xTail = xTail.next;
yTail = yTail.next;
}
return false;
}
}
class Takl {
static ListElement takl(ListElement x, ListElement y, ListElement z) {
if (ListElement.isShorter(y, x)) {
return takl(takl(x.next, y, z),
takl(y.next, z, x),
takl(z.next, x, y));
} else {
return z;
}
}
}
class TaklBenchmark extends BenchmarkBase {
const TaklBenchmark() : super("Takl");
void warmup() {
Takl.takl(ListElement.makeList(8),
ListElement.makeList(4),
ListElement.makeList(3));
}
void exercise() {
// This value has been copied from benchpress.js, so that we can compare
// performance.
ListElement result = Takl.takl(ListElement.makeList(15),
ListElement.makeList(10),
ListElement.makeList(6));
if (result.length != 10) {
int len = result.length;
Error.error("Wrong result: $len should be: 10");
}
}
static void main() {
new TaklBenchmark().report();
}
}
// M a i n
class BenchPress {
static void mainWithArgs(List<String> args) {
List<BenchmarkBase> benchmarks = [
new BubbleSortBenchmark(),
new FibBenchmark(),
new LoopBenchmark(),
new PermuteBenchmark(),
new QueensBenchmark(),
new QuickSortBenchmark(),
new RecurseBenchmark(),
new SieveBenchmark(),
new SumBenchmark(),
new TakBenchmark(),
new TaklBenchmark(),
new TowersBenchmark(),
new TreeSortBenchmark(),
];
if (args.length > 0) {
String benchName = args[0];
bool foundBenchmark = false;
benchmarks.forEach((bench) {
if (bench.name == benchName) {
foundBenchmark = true;
bench.report();
}
});
if (!foundBenchmark) {
Error.error("Benchmark not found: $benchName");
}
return;
}
double logMean = 0.0;
benchmarks.forEach((bench) {
double benchScore = bench.measure();
String name = bench.name;
print("$name: $benchScore");
logMean += Math.log(benchScore);
});
logMean = logMean / benchmarks.length;
double score = Math.pow(Math.E, logMean);
print("BenchPress (average): $score");
}
// TODO(floitsch): let main accept arguments from the command line.
static void main() {
mainWithArgs([]);
}
}
class BenchmarkBase {
final String name;
// Empty constructor.
const BenchmarkBase(String name) : this.name = name;
// The benchmark code.
// This function is not used, if both [warmup] and [exercise] are overwritten.
void run() { }
// Runs a short version of the benchmark. By default invokes [run] once.
void warmup() {
run();
}
// Exercices the benchmark. By default invokes [run] 10 times.
void exercise() {
for (int i = 0; i < 10; i++) {
run();
}
}
// Not measured setup code executed prior to the benchmark runs.
void setup() { }
// Not measures teardown code executed after the benchark runs.
void teardown() { }
// Measures the score for this benchmark by executing it repeately until
// time minimum has been reached.
static double measureFor(Function f, int timeMinimum) {
int time = 0;
int iter = 0;
DateTime start = new DateTime.now();
while (time < timeMinimum) {
f();
time = (new DateTime.now().difference(start)).inMilliseconds;
iter++;
}
// Force double result by using a double constant.
return (1000.0 * iter) / time;
}
// Measures the score for the benchmark and returns it.
double measure() {
setup();
// Warmup for at least 100ms. Discard result.
measureFor(() { this.warmup(); }, -100);
// Run the benchmark for at least 2000ms.
double result = measureFor(() { this.exercise(); }, -2000);
teardown();
return result;
}
void report() {
double score = measure();
print("name: $score");
}
}
class Logger {
static print(object) {
printobject(object);
}
static printobject(obj) { }
}
//
// Dromaeo ObjectString
// Adapted from Mozilla JavaScript performance test suite.
// Microtests of strings (concatenation, methods).
class ObjectString extends BenchmarkBase {
const ObjectString() : super("Dromaeo.ObjectString");
static void main() {
new ObjectString().report();
}
static void print(String str) {
print(str);
}
String getRandomString(int characters) {
var result = "";
for (var i = 0; i < characters; i++) {
result += Strings.
createFromCodePoints([(25 * Math.random()).toInt() + 97]);
}
result += result;
result += result;
return result;
}
void run() {
//JS Dromeaeo uses 16384
final ITERATE1 = 384;
//JS Dromeaeo uses 80000
final ITERATE2 = 80;
//JS Dromeaeo uses 5000
final ITERATE3 = 50;
//JS Dromeaeo uses 5000
final ITERATE4 = 1;
//JS Dromaeo uses 5000
final ITERATE5 = 1000;
var result;
var text = getRandomString(ITERATE1);
ConcatStringBenchmark.test(ITERATE2);
ConcatStringFromCharCodeBenchmark.test(ITERATE2);
StringSplitBenchmark.test(text);
StringSplitOnCharBenchmark.test(text);
text += text;
CharAtBenchmark.test(text, ITERATE3);
NumberBenchmark.test(text, ITERATE3);
CodeUnitAtBenchmark.test(text, ITERATE3);
IndexOfBenchmark.test(text, ITERATE3);
LastIndexOfBenchmark.test(text, ITERATE3);
SliceBenchmark.test(text, ITERATE4);
SubstrBenchmark.test(text, ITERATE4);
SubstringBenchmark.test(text, ITERATE4);
ToLowerCaseBenchmark.test(text, ITERATE5);
ToUpperCaseBenchmark.test(text, ITERATE5);
ComparingBenchmark.test(text, ITERATE5);
}
}
class ConcatStringBenchmark {
ConcatStringBenchmark() {}
static String test(var iterations) {
var str = "";
for (var i = 0; i < iterations; i++) {
str += "a";
}
return str;
}
}
class ConcatStringFromCharCodeBenchmark {
ConcatStringFromCharCodeBenchmark() {}
static String test(var iterations) {
var str = "";
for (var i = 0; i < (iterations / 2); i++) {
str += Strings.createFromCodePoints([97]);
}
return str;
}
}
class StringSplitBenchmark {
StringSplitBenchmark() {}
static List<String> test(String input) {
return input.split("");
}
}
class StringSplitOnCharBenchmark {
StringSplitOnCharBenchmark() {}
static List<String> test(String input) {
String multiple = input;
multiple += multiple;
multiple += multiple;
multiple += multiple;
multiple += multiple;
return multiple.split("a");
}
}
class CharAtBenchmark {
CharAtBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input[0];
str = input[input.length - 1];
str = input[150]; //set it to 15000
str = input[120]; //set it to 12000
}
return str;
}
}
class NumberBenchmark {
NumberBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input[0];
str = input[input.length - 1];
str = input[150]; //set it to 15000
str = input[100]; //set it to 10000
str = input[50]; //set it to 5000
}
return str;
}
}
class CodeUnitAtBenchmark {
CodeUnitAtBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.codeUnitAt(0);
str = input.codeUnitAt(input.length - 1);
str = input.codeUnitAt(150); //set it to 15000
str = input.codeUnitAt(100); //set it to 10000
str = input.codeUnitAt(50); //set it to 5000
}
return str;
}
}
class IndexOfBenchmark {
IndexOfBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.indexOf("a", 0);
str = input.indexOf("b", 0);
str = input.indexOf("c", 0);
str = input.indexOf("d", 0);
}
return str;
}
}
class LastIndexOfBenchmark {
LastIndexOfBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.lastIndexOf("a", input.length - 1);
str = input.lastIndexOf("b", input.length - 1);
str = input.lastIndexOf("c", input.length - 1);
str = input.lastIndexOf("d", input.length - 1);
}
return str;
}
}
class SliceBenchmark {
SliceBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length - 1);
str = input.substring(0, 5);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 1);
str = input.substring(150, 155); //set to 15000 and 15005
str = input.substring(120, input.length-1); //set to 12000
}
return str;
}
}
class SubstrBenchmark {
SubstrBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length-1);
str = input.substring(0, 4);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 6);
str = input.substring(150, 154); //set to 15000 and 15005
str = input.substring(120, 124); //set to 12000
}
return str;
}
}
class SubstringBenchmark {
SubstringBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < iterations; j++) {
str = input.substring(0, input.length - 1);
str = input.substring(0, 4);
str = input.substring(input.length - 1, input.length - 1);
str = input.substring(input.length - 6, input.length - 2);
str = input.substring(150, 154); //set to 15000 and 15005
str = input.substring(120, input.length - 2); //set to 12000
}
return str;
}
}
class ToLowerCaseBenchmark {
ToLowerCaseBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < (iterations / 1000); j++) {
str = Ascii.toLowerCase(input);
}
return str;
}
}
class ToUpperCaseBenchmark {
ToUpperCaseBenchmark() {}
static String test(String input, var iterations) {
var str;
for (var j = 0; j < (iterations / 1000); j++) {
str = Ascii.toUpperCase(input);
}
return str;
}
}
class ComparingBenchmark {
ComparingBenchmark() {}
static bool test(String input, var iterations) {
var tmp = "a${input}a";
var tmp2 = "a${input}a";
var res;
for (var j = 0; j < (iterations / 1000); j++) {
res = (tmp.compareTo(tmp2) == 0);
res = (tmp.compareTo(tmp2) < 0);
res = (tmp.compareTo(tmp2) > 0);
}
return res;
}
}
// Benchmarks basic message communication between two isolates.
class Benchmark1 {
static const MESSAGES = 10000;
static const INIT_MESSAGE = 0;
static const TERMINATION_MESSAGE = -1;
static const WARMUP_TIME = 1000;
static const RUN_TIME = 1000;
static const RUNS = 5;
static int run() {
return _run;
}
static void add_result(var opsms) {
_run++;
_opsms += opsms;
}
static void get_result() {
return _opsms / _run;
}
static void init() {
_run = 0;
_opsms = 0.0;
}
static void main() {
init();
PingPongGame pingPongGame = new PingPongGame();
}
static var _run;
static var _opsms;
}
class PingPongGame {
PingPongGame()
: _ping = new ReceivePort(),
_pingPort = _ping.toSendPort(),
_pong = null,
_warmedup = false,
_iterations = 0 {
SendPort _pong = spawnFunction(pong);
play();
}
void startRound() {
_iterations++;
_pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
}
void evaluateRound() {
int time = (new DateTime.now().difference(_start)).inMilliseconds;
if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
startRound();
} else if (!_warmedup) {
_warmedup = true;
_start = new DateTime.now();
_iterations = 0;
startRound();
} else if (_warmedup && time < Benchmark1.RUN_TIME) {
startRound();
} else {
shutdown();
Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
if (Benchmark1.run() < Benchmark1.RUNS) {
new PingPongGame();
} else {
print("PingPong: ", Benchmark1.get_result());
}
}
}
void play() {
_ping.receive((int message, SendPort replyTo) {
if (message < Benchmark1.MESSAGES) {
_pong.send(++message, null);
} else {
evaluateRound();
}
});
_start = new DateTime.now();
startRound();
}
void shutdown() {
_pong.send(Benchmark1.TERMINATION_MESSAGE, null);
_ping.close();
}
DateTime _start;
SendPort _pong;
SendPort _pingPort;
ReceivePort _ping;
bool _warmedup;
int _iterations;
}
void pong() {
port.receive((message, SendPort replyTo) {
if (message == Benchmark1.INIT_MESSAGE) {
replyTo.send(message, null);
} else if (message == Benchmark1.TERMINATION_MESSAGE) {
port.close();
} else {
replyTo.send(message, null);
}
});
}
class ManyGenericInstanceofTest {
static testMain() {
for (int i = 0; i < 5000; i++) {
GenericInstanceof.testMain();
}
}
}
// ---------------------------------------------------------------------------
// THE REST OF THIS FILE COULD BE AUTOGENERATED
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// tests/isolate/spawn_test.dart
// ---------------------------------------------------------------------------
spawn_test_main() {
test("spawn a new isolate", () {
SendPort port = spawnFunction(entry);
port.call(42).then(expectAsync1((message) {
Expect.equals(42, message);
}));
});
}
void entry() {
port.receive((message, SendPort replyTo) {
Expect.equals(42, message);
replyTo.send(42, null);
port.close();
});
}
// ---------------------------------------------------------------------------
// tests/isolate/isolate_negative_test.dart
// ---------------------------------------------------------------------------
void isolate_negative_entry() {
port.receive((ignored, replyTo) {
replyTo.send("foo", null);
});
}
isolate_negative_test_main() {
test("ensure isolate code is executed", () {
SendPort port = spawnFunction(isolate_negative_entry);
port.call("foo").then(expectAsync1((message) {
Expect.equals(true, "Expected fail"); // <=-------- Should fail here.
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/message_test.dart
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Message passing test.
// ---------------------------------------------------------------------------
class MessageTest {
static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
static const List list2 = const [null, list1, list1, list1, list1];
static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
static const Map map1 = const {
"a=1" : 1, "b=2" : 2, "c=3" : 3,
};
static const Map map2 = const {
"list1" : list1, "list2" : list2, "list3" : list3,
};
static const List list4 = const [map1, map2];
static const List elms = const [
list1, list2, list3, list4,
];
static void VerifyMap(Map expected, Map actual) {
Expect.equals(true, expected is Map);
Expect.equals(true, actual is Map);
Expect.equals(expected.length, actual.length);
testForEachMap(key, value) {
if (value is List) {
VerifyList(value, actual[key]);
} else {
Expect.equals(value, actual[key]);
}
}
expected.forEach(testForEachMap);
}
static void VerifyList(List expected, List actual) {
for (int i = 0; i < expected.length; i++) {
if (expected[i] is List) {
VerifyList(expected[i], actual[i]);
} else if (expected[i] is Map) {
VerifyMap(expected[i], actual[i]);
} else {
Expect.equals(expected[i], actual[i]);
}
}
}
static void VerifyObject(int index, var actual) {
var expected = elms[index];
Expect.equals(true, expected is List);
Expect.equals(true, actual is List);
Expect.equals(expected.length, actual.length);
VerifyList(expected, actual);
}
}
pingPong() {
int count = 0;
port.receive((var message, SendPort replyTo) {
if (message == -1) {
port.close();
replyTo.send(count, null);
} else {
// Check if the received object is correct.
if (count < MessageTest.elms.length) {
MessageTest.VerifyObject(count, message);
}
// Bounce the received object back so that the sender
// can make sure that the object matches.
replyTo.send(message, null);
count++;
}
});
}
message_test_main() {
test("send objects and receive them back", () {
SendPort remote = spawnFunction(pingPong);
// Send objects and receive them back.
for (int i = 0; i < MessageTest.elms.length; i++) {
var sentObject = MessageTest.elms[i];
// TODO(asiva): remove this local var idx once thew new for-loop
// semantics for closures is implemented.
var idx = i;
remote.call(sentObject).then(expectAsync1((var receivedObject) {
MessageTest.VerifyObject(idx, receivedObject);
}));
}
// Send recursive objects and receive them back.
List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
List local_list2 = [null, local_list1, local_list1 ];
List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
List sendObject = new List(5);
sendObject[0] = local_list1;
sendObject[1] = sendObject;
sendObject[2] = local_list2;
sendObject[3] = sendObject;
sendObject[4] = local_list3;
remote.call(sendObject).then((var replyObject) {
Expect.equals(true, sendObject is List);
Expect.equals(true, replyObject is List);
Expect.equals(sendObject.length, replyObject.length);
Expect.equals(true, identical(replyObject[1], replyObject));
Expect.equals(true, identical(replyObject[3], replyObject));
Expect.equals(true, identical(replyObject[0], replyObject[2][1]));
Expect.equals(true, identical(replyObject[0], replyObject[2][2]));
Expect.equals(true, identical(replyObject[2], replyObject[4][0]));
Expect.equals(true, identical(replyObject[0][0], replyObject[0][2]));
// Bigint literals are not canonicalized so do a == check.
Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
});
// Shutdown the MessageServer.
remote.call(-1).then(expectAsync1((int message) {
Expect.equals(MessageTest.elms.length + 1, message);
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/request_reply_test.dart
// ---------------------------------------------------------------------------
void request_reply_entry() {
port.receive((message, SendPort replyTo) {
replyTo.send(message + 87);
port.close();
});
}
void request_reply_main() {
test("call", () {
SendPort port = spawnFunction(request_reply_entry);
port.call(42).then(expectAsync1((message) {
Expect.equals(42 + 87, message);
}));
});
test("send", () {
SendPort port = spawnFunction(request_reply_entry);
ReceivePort reply = new ReceivePort();
port.send(99, reply.toSendPort());
reply.receive(expectAsync2((message, replyTo) {
Expect.equals(99 + 87, message);
reply.close();
}));
});
}
// ---------------------------------------------------------------------------
// tests/isolate/count_test.dart
// ---------------------------------------------------------------------------
void countMessages() {
int count = 0;
port.receive((int message, SendPort replyTo) {
if (message == -1) {
Expect.equals(10, count);
replyTo.send(-1, null);
port.close();
return;
}
Expect.equals(count, message);
count++;
replyTo.send(message * 2, null);
});
}
void count_main() {
test("count 10 consecutive messages", () {
int count = 0;
SendPort remote = spawnFunction(countMessages);
ReceivePort local = new ReceivePort();
SendPort reply = local.toSendPort();
local.receive(expectAsync2((int message, SendPort replyTo) {
if (message == -1) {
Expect.equals(11, count);
local.close();
return;
}
Expect.equals((count - 1) * 2, message);
remote.send(count++, reply);
if (count == 10) {
remote.send(-1, reply);
}
}, 11));
remote.send(count++, reply);
});
}
// ---------------------------------------------------------------------------
// tests/isolate/mandel_isolate_test.dart
// ---------------------------------------------------------------------------
const TERMINATION_MESSAGE = -1;
const N = 100;
const ISOLATES = 20;
mandel_main() {
test("Render Mandelbrot in parallel", () {
final state = new MandelbrotState();
state._validated.future.then(expectAsync1((result) {
expect(result, isTrue);
}));
for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
});
}
class MandelbrotState {
MandelbrotState() {
_result = new List<List<int>>(N);
_lineProcessedBy = new List<LineProcessorClient>(N);
_sent = 0;
_missing = N;
_validated = new Completer<bool>();
}
void startClient(int id) {
assert(_sent < N);
final client = new LineProcessorClient(this, id);
client.processLine(_sent++);
}
void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
assert(_result[y] == null);
_result[y] = line;
_lineProcessedBy[y] = client;
if (_sent != N) {
client.processLine(_sent++);
} else {
client.shutdown();
}
// If all lines have been computed, validate the result.
if (--_missing == 0) {
_printResult();
_validateResult();
}
}
void _validateResult() {
// TODO(ngeoffray): Implement this.
_validated.complete(true);
}
void _printResult() {
var output = new StringBuffer();
for (int i = 0; i < _result.length; i++) {
List<int> line = _result[i];
for (int j = 0; j < line.length; j++) {
if (line[j] < 10) output.write("0");
output.write(line[j]);
}
output.write("\n");
}
// print(output);
}
List<List<int>> _result;
List<LineProcessorClient> _lineProcessedBy;
int _sent;
int _missing;
Completer<bool> _validated;
}
class LineProcessorClient {
LineProcessorClient(MandelbrotState this._state, int this._id) {
_port = spawnFunction(processLines);
}
void processLine(int y) {
_port.call(y).then((List<int> message) {
_state.notifyProcessedLine(this, y, message);
});
}
void shutdown() {
_port.send(TERMINATION_MESSAGE, null);
}
MandelbrotState _state;
int _id;
SendPort _port;
}
List<int> processLine(int y) {
double inverseN = 2.0 / N;
double Civ = y * inverseN - 1.0;
List<int> result = new List<int>(N);
for (int x = 0; x < N; x++) {
double Crv = x * inverseN - 1.5;
double Zrv = Crv;
double Ziv = Civ;
double Trv = Crv * Crv;
double Tiv = Civ * Civ;
int i = 49;
do {
Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
Zrv = Trv - Tiv + Crv;
Trv = Zrv * Zrv;
Tiv = Ziv * Ziv;
} while (((Trv + Tiv) <= 4.0) && (--i > 0));
result[x] = i;
}
return result;
}
void processLines() {
port.receive((message, SendPort replyTo) {
if (message == TERMINATION_MESSAGE) {
assert(replyTo == null);
port.close();
} else {
replyTo.send(processLine(message), null);
}
});
}