Skip to content

Commit

Permalink
optimized implementations of sum() and product()
Browse files Browse the repository at this point in the history
this is based on code + ideas by @jvasileff in #728, but using native
  • Loading branch information
gavinking committed Oct 1, 2015
1 parent ae32cbc commit c0d88c8
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 5 deletions.
49 changes: 45 additions & 4 deletions src/ceylon/language/product.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
product of the values.
{Float+} values = ... ;
Float result = sum(values);
Float result = product(values);
For the case of a possibly-empty stream, form a nonempty
stream starting with the unit element (the [[multiplicative
Expand All @@ -12,11 +12,52 @@
Float result = product { 1.0, *values };"
see (`function sum`)
tagged("Streams", "Numbers")
shared Value product<Value>({Value+} values)
shared native Value product<Value>({Value+} values)
given Value satisfies Numeric<Value>;

shared native("js") Value product<Value>({Value+} values)
given Value satisfies Numeric<Value> {
variable value product = values.first;
for (val in values.rest) {
value it = values.iterator();
assert (!is Finished first = it.next());
variable value product = first;
while (!is Finished val = it.next()) {
product *= val;
}
return product;
}

shared native("jvm") Value product<Value>({Value+} values)
given Value satisfies Numeric<Value> {
value it = values.iterator();
switch (first = it.next())
case (is Integer) {
// unbox; don't infer type Value&Integer
variable Integer product = first;
while (is Integer val = it.next()) {
Integer unboxed = val;
product *= unboxed;
}
assert (is Value result = product);
return result;
}
case (is Float) {
// unbox; don't infer type Value&Float
variable Float product = first;
while (is Float val = it.next()) {
Float unboxed = val;
product *= unboxed;
}
assert (is Value result = product);
return result;
}
case (is Finished) {
assert (false);
}
else {
variable value product = first;
while (!is Finished val = it.next()) {
product *= val;
}
return product;
}
}
41 changes: 40 additions & 1 deletion src/ceylon/language/sum.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
Float total = sum { 0.0, *values };"
see (`function product`)
tagged("Streams", "Numbers")
shared Value sum<Value>({Value+} values)
shared native Value sum<Value>({Value+} values)
given Value satisfies Summable<Value>;

shared native("js") Value sum<Value>({Value+} values)
given Value satisfies Summable<Value> {
value it = values.iterator();
assert (!is Finished first = it.next());
Expand All @@ -22,3 +25,39 @@ shared Value sum<Value>({Value+} values)
}
return sum;
}

shared native("jvm") Value sum<Value>({Value+} values)
given Value satisfies Summable<Value> {
value it = values.iterator();
switch (first = it.next())
case (is Integer) {
// unbox; don't infer type Value&Integer
variable Integer sum = first;
while (is Integer val = it.next()) {
Integer unboxed = val;
sum += unboxed;
}
assert (is Value result = sum);
return result;
}
case (is Float) {
// unbox; don't infer type Value&Float
variable Float sum = first;
while (is Float val = it.next()) {
Float unboxed = val;
sum += unboxed;
}
assert (is Value result = sum);
return result;
}
case (is Finished) {
assert (false);
}
else {
variable value sum = first;
while (!is Finished val = it.next()) {
sum += val;
}
return sum;
}
}

0 comments on commit c0d88c8

Please sign in to comment.