In my testing of the TS/Vitest branch I added stress-tests and that led to the discovery of an interesting bug.
In testing the TSLinearSeries I added a stress-test and I wanted to be able to predict the outcome. So I added a loop that would add datapoints following a y = x line perfectly, just to verify what would happen to the metrics if you had 500 datapoints (as my maximum observed C2 RowErg recovery length is around 500 in a final stroke). I got a HEAP MEMORY error as a response, after about 65 datapoints. Not really what I expected, especially as that would imply that a C2 RowErg shouldn't work (which it does in practice).
After a lot of testing and then some thinking, I discovered why. When all data is alligned really perfectly into a straight line, you get a lot of truly identical datapoints added to the Binary Search Tree (+/- 0.5 * datapoints^2 of slopes). In the Binary Search Tree this essentially results in a linked list, which ORM traverses recursively. This is where the heap memory comes in: the BST has become too deep to be traversed recursively, so the app crashes due to the recursion.
In essence, when you have perfect data in perfect alignment, after about 65 datapoints the perfection will kill the drag calculation. A structural ascending or descending group of slopes (a parabola) will result in the same failure. As soon as there is random noise, the datapoints will spread randomly across the tree and the problem is gone.
Given the state of the average rowing machine and our noise filtering, one might consider it a bit of a academic problem. But I've decided to fix it regardless. I will do this by adding balancing functionality in 0.9.8 (code available via the giftshop), allowing a maximum unbalance of 30% across two subtrees under each node. With this adaptation I can insert over 4000 perfectly alligned datapoints (resulting in +/-8.000.000 identical slopes in the BST) without problems.
It does come at a slight cost: execution time for 6,400,000 inserts was about 66,735 ms, and has now risen to about 71,672 ms. Not a really big thing, but something to keep an eye on.
In my testing of the TS/Vitest branch I added stress-tests and that led to the discovery of an interesting bug.
In testing the TSLinearSeries I added a stress-test and I wanted to be able to predict the outcome. So I added a loop that would add datapoints following a
y = xline perfectly, just to verify what would happen to the metrics if you had 500 datapoints (as my maximum observed C2 RowErg recovery length is around 500 in a final stroke). I got a HEAP MEMORY error as a response, after about 65 datapoints. Not really what I expected, especially as that would imply that a C2 RowErg shouldn't work (which it does in practice).After a lot of testing and then some thinking, I discovered why. When all data is alligned really perfectly into a straight line, you get a lot of truly identical datapoints added to the Binary Search Tree (+/- 0.5 * datapoints^2 of slopes). In the Binary Search Tree this essentially results in a linked list, which ORM traverses recursively. This is where the heap memory comes in: the BST has become too deep to be traversed recursively, so the app crashes due to the recursion.
In essence, when you have perfect data in perfect alignment, after about 65 datapoints the perfection will kill the drag calculation. A structural ascending or descending group of slopes (a parabola) will result in the same failure. As soon as there is random noise, the datapoints will spread randomly across the tree and the problem is gone.
Given the state of the average rowing machine and our noise filtering, one might consider it a bit of a academic problem. But I've decided to fix it regardless. I will do this by adding balancing functionality in 0.9.8 (code available via the giftshop), allowing a maximum unbalance of 30% across two subtrees under each node. With this adaptation I can insert over 4000 perfectly alligned datapoints (resulting in +/-8.000.000 identical slopes in the BST) without problems.
It does come at a slight cost: execution time for 6,400,000 inserts was about 66,735 ms, and has now risen to about 71,672 ms. Not a really big thing, but something to keep an eye on.