Proyecto

General

Perfil

Perfomance penalty of `javautilStack` » Histórico » Versión 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.
Volver al inicio