]
Geoffrey De Smet commented on DROOLS-1175:
------------------------------------------
I ran benchmarks on this, and these are the percentage gains I am seeing:
||Example||new||old||gain||
|Cloud Balancing |104327 |95582 |9.15%|
|Machine Reassignment |169405 |168904 |0.30%|
|Course Scheduling |10319 |10753 |-4.04%|
|Examination |12649 |12957 |-2.38%|
|Nurse Rostering |6552 |6437 |1.79%|
|TravelingTournament |2262 |2243 |0.85%|
Accumulates: sum(Long), sum(BigDecimal), sum(Integer) and
sum(BigInteger)
-------------------------------------------------------------------------
Key: DROOLS-1175
URL:
https://issues.jboss.org/browse/DROOLS-1175
Project: Drools
Issue Type: Feature Request
Components: core engine
Affects Versions: 6.4.0.Final
Reporter: Geoffrey De Smet
Assignee: Mario Fusco
Fix For: 7.0.0.Beta2
Currently, when summing longs in an accumulate, we get something like this:
{code}
when ...
$t : Number(...) from accumulate(...,
sum($p.getLongWeight()))
then scoreHolder.addHard($t.longValue());
{code}
This has 3 problems:
- *Loss of precision*: the long sum `1881617265586265321L` will incorrectly return
`1.88161726558626534E18`, so `13` too much! The BigDecimal sum of `0.09` and `0.01` will
also be incorrect.
- *Loss of performance*: Summing with a Double total is significantly slower than summing
with a Long total or an Integer total.
- Example complexity (minor, not all of us agree on this argument): the use of `Number`
is an abstraction that doesn't bring any value to the use case. It's worthless
complexity.
Solution proposal A) for 7.0 as discussed with Mario:
Based on the argument type to the sum function, the compiler selects a different sum
function implementation. This is similar to java overloading mechanism, where
`System.out.println(1)` selects a different method implementation than
`System.out.println(2.0)`.
Support sum(Long):
{code}
when ...
$t : Long(...) from accumulate(...,
sum($p.getLongWeight()))
then scoreHolder.addHard($t);
{code}
and sum(BigDecimal):
{code}
when ...
$t : BigDecimal(...) from accumulate(...,
sum($p.getBigDecimalWeight()))
then scoreHolder.addHard($t);
{code}
and also support sum(Integer) and sum(BigInteger).
If this works well, we can consider it for other functions as well in a different jira
issue.
Special case 1: sum(Number) should default to sum(Double) for backwards compatibility.
{code}
when ...
$t : Number(...) from accumulate(...,
sum($p.getNumberWeight()))
then scoreHolder.addHard($t.doubleValue());
{code}
Not-so-special case 2: to sum integers into a long total, the user should just use:
{code}
$t : Long(...) from accumulate(...,
sum((long) $p.getIntWeight()))
{code}