mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
029b1cb948
R=kevmoo@google.com BUG= Review-Url: https://codereview.chromium.org/2957593002 .
1551 lines
37 KiB
Dart
1551 lines
37 KiB
Dart
// 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();
|
|
}
|
|
|
|
// Exercises 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 benchmark 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];
|
|
remote.call(sentObject).then(expectAsync1((var receivedObject) {
|
|
MessageTest.VerifyObject(i, 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);
|
|
}
|
|
});
|
|
}
|