Perfomance penalty of `javautilStack` » History » Version 2
Federico Vera, 2018-07-09 17:52
| 1 | 1 | Federico Vera | # Perfomance penalty of `java.util.Stack` |
|---|---|---|---|
| 2 | 2 | Federico Vera | |
| 3 | This is copy of the original [#26](https://github.com/fasseg/exp4j/issues/26) discussion |
||
| 4 | |||
| 5 | I've been profiling `exp4j` in particular `Expression.evaluate()`, from the profiling I gathered the following data (using Netbeans profiler): |
||
| 6 | |||
| 7 | ``` |
||
| 8 | Using Stack 100.00% |
||
| 9 | |||
| 10 | evaluate() 19633 100.00% |
||
| 11 | Total Stack 10900 55.52% |
||
| 12 | Stack.pop() 5219 26.58% |
||
| 13 | Stack.push() 3361 17.12% |
||
| 14 | Double.valueOf() 2320 11.82% |
||
| 15 | HashMap.get() 1479 7.53% |
||
| 16 | ----------------------------------- |
||
| 17 | Using LinkedList 85.48% |
||
| 18 | |||
| 19 | evaluate() 16782 100.00% |
||
| 20 | Total LinkedList 8938 53.26% |
||
| 21 | LinkedList.push() 3670 21.87% |
||
| 22 | LinkedList.pop() 2705 16.12% |
||
| 23 | Double.valueOf() 2563 15.27% |
||
| 24 | HashMap.get() 1493 8.90% |
||
| 25 | ----------------------------------- |
||
| 26 | Using ArrayStack 46.45% |
||
| 27 | |||
| 28 | evaluate() 9120 100.00% |
||
| 29 | Total ArrayStack 971 10.65% |
||
| 30 | ArrayStack.push() 590 6.47% |
||
| 31 | ArrayStack.pop() 381 4.18% |
||
| 32 | HashMap.get() 1452 15.92% |
||
| 33 | ``` |
||
| 34 | |||
| 35 | The results show that most of the time used by `Expression.evaluate()` is wasted on the use of `java.util.Stack` which is backed by `java.util.Vector`. |
||
| 36 | I tested again using `java.util.LinkedList` which can be used as a drop in replacement for `java.util.stack`, it shows some improvements (~15%) but the boxing/unboxing process still takes up a lot of time. |
||
| 37 | Finally I've created a simple `ArrayStack` class that works with an array of doubles directly and doesn't need to box/unbox nor to adapt the methods from `java.util.Vector` to `push()` and `pop()`. The final result is that the `Expression.evaluate()` uses less than 50% of the time. |
||
| 38 | |||
| 39 | About the table: |
||
| 40 | The second column of the table is the total time in _ms_ used by the method in 1M excecutions. |
||
| 41 | |||
| 42 | The profiled code was: |
||
| 43 | |||
| 44 | ``` java |
||
| 45 | public class Test { |
||
| 46 | static final String EXPRESSION = "log(x) - y * sqrt(x^cos(y)) " |
||
| 47 | + "+ 43 / 9 * sin(x) - 3 ^ (-3)"; |
||
| 48 | public static void main(String[] args) { |
||
| 49 | final Expression expression = new ExpressionBuilder(EXPRESSION) |
||
| 50 | .variables("x", "y") |
||
| 51 | .build(); |
||
| 52 | Random rnd = new Random(); |
||
| 53 | double val = 0; |
||
| 54 | int count = 0; |
||
| 55 | while (count < 1000000) { |
||
| 56 | expression.setVariable("x", rnd.nextDouble()); |
||
| 57 | expression.setVariable("y", rnd.nextDouble()); |
||
| 58 | val += expression.evaluate(); |
||
| 59 | count++; |
||
| 60 | } |
||
| 61 | System.out.println(val); |
||
| 62 | } |
||
| 63 | } |
||
| 64 | ``` |
||
| 65 | |||
| 66 | Looking forward now most of the time seems to be used retrieving the variable values. |