prmr / JetUML

A desktop application for fast UML diagramming.
GNU General Public License v3.0
625 stars 125 forks source link

Issue375 : Add a NodeStorage, unit tests, and a performance test. #444

Closed delphinepilon closed 2 years ago

delphinepilon commented 2 years ago

Add NodeStorage

As described in the commit message, a NodeStorage was added to each NodeViewer to improve the performance of DiagramViewer.draw(diagram). For each call to NodeViewer.getBounds(node), if the NodeStorage is deactivated, then the bounds will be computed as returned. If the NodeStorage is activated, then it will first check whether the bounds have already been computed, and if so, it will return them directly. Otherwise, it will compute the bounds to be returned and store them for future reference. As soon as the NodeStorage is deactivated, it is cleared.

I made use of the Template Method design pattern in AbstractNodeViewer by defining the abstract method internalGetBounds(Node) which returns a Rectangle. A method reference to internalGetBounds(Node) is passed to the NodeStorage to indicate how to compute the bounds for each of the different NodeViewers.

This NodeStorage is activated at the beginning of the method DiagramViewer.draw(diagram) and is deactivated/cleared at the end of the same method.

Add a performance test

The performance test is defined in the class TestPerformance, in a main method. Originally, it could be executed from the test folder if the package was mentioned in module-info.java. However, this seems to have changed. I have only been able to execute the main method from the src folder (no longer needs to be mentioned in module-info.java). If there is a better alternative, we can move the file elsewhere.

A performance test was added to be able to witness the benefits of adding a NodeStorage. The test loads a class diagram into memory from an external file and records the execution time of DiagramViewer.draw(diagram). To increase the accuracy of the reported duration, the average duration of ten calls to draw is reported, omitting the initial outlier. The diagram under observation has 11 nodes. There are a total of 1342 calls to NodeStorage.getBounds(Node, Function<Node, Rectangle>), of which 11 are cache misses and 1331 are cache hits. The duration reported by the performance test dropped from approximately 26ms to 16ms with the NodeStorage implementation.