-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: simplify flatten function using Array.prototype.flat #3354
base: develop
Are you sure you want to change the base?
Conversation
That is nice. I would like to do that, though looking at support of |
Hi Jos, thanks for reviewing this. Ok, maybe later, also noticed this is a bit faster. |
Great that it is faster, that makes sense! What we can do for now is: use |
It makes sense. In the latest commit I included the fallback and also changed to use for loops thus closing the gap in performance. Tested for performance
I've been reviewing the algorithms in I'm testing a flatten function that skips some validations if the array is in matrix form that shows like 2X improvement. Will give it a try next and make a new commit in a few days. |
By changing the |
Now there is a faster flattening algorithm for Matrices and Arrays with an homogenous size. |
The algorithm for arrays with homogeneous sizes works faster, but verifying its applicability is costly. DenseMatrix instances are already validated. However, for arrays, validation is still required. This presents a tradeoff: it's advantageous for large arrays but not for small ones. Considerations:
|
The latest commit return the algorithms in a way that they should always be faster regardless of the case, matrix, array with homogeneous size and array with inhomogeneous size. There is still an area of opportunity to check if the array has homogenous size that might be faster for large arrays. |
Ah, I see what you did: two different implementations. So how much performance difference does it yield in the end? I think we should be careful overoptimizing this, since a different browser engine or the next update of Chrome may do things differently again. So, the additional code and complexity should be really worth it. Is there a benchmark test already so I can do some comparisons on my machine? |
Hi Jos, thank you for reviewing this. Here are the results I got and I'm including the code at the end:
Those are very valid concerns
I don't have a strong opinion about this, I could either change to map and test again, include flatten as a method for Appendiximport { Bench } from 'tinybench'
import { DenseMatrix, flatten, random } from '../../lib/esm/index.js'
import { formatTaskResult } from './utils/formatTaskResult.js'
const genericMatrix = new DenseMatrix(random([10, 10, 10, 10]))
const numberMatrix = new DenseMatrix(genericMatrix, 'number')
const arrayWithHomogeneousSize = genericMatrix.valueOf()
const arrayWithNonHomogeneousSize = [random([10, 10, 10]), random([10, 9, 9]), random()]
const bench = new Bench({ time: 500, iterations: 100 })
.add('flatten(Matrix)', () => {
flatten(genericMatrix)
})
.add('flatten(numberMatrix)', () => {
flatten(numberMatrix)
})
.add('flatten(arrayWithHomogeneousSize)', () => {
flatten(arrayWithHomogeneousSize)
})
.add('flatten(arrayWithNonHomogeneousSize)', () => {
flatten(arrayWithNonHomogeneousSize)
})
.add('flatten(array).map(abs)', () => {
numberMatrix.map(abs)
})
bench.addEventListener('cycle', (event) => console.log(formatTaskResult(bench, event.task)))
await bench.run() |
Thanks for testing and for sharing your benchmark. I've did run the benchmark too, but in my case the results are worse than develop 🤔 (running Node.js 20)
I don't understand the big differences in flattening an array between your machine and mine, maybe I'm doing something wrong. Anyway, even in the most positive case (your results) I have the feeling that the differences are so small that it is not worth the additional complexity of two different implementations. What do you think? |
That's very interesting. I did test using node v23.6.1 using a windows machine with 32 GB RAM and a Core i9, I have another machine available, will try to run the same benchmark on that one. To develop these algorithms I was mostly using firefox and jsbench. I had high hopes for the skip made for the case of the homogenous size as it made a significant improvement in my tests. I'm including a link on jsbench. |
👍 please don't spend too much time on this, we shouldn't overengineer or micro opimize this 😅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Jos
I did spend a little time testing on another computer and even the method of arr.flatten(Infinity) wasn't a consistent improvement in speed in node v22.11.0. I think what I was seeing as impropvement was more Firefox and Safari related.
So I reverted back to the original form, the only notable improvement in speed I found was on the call to flatten on a matrix, it sped up by using valueOf()
instead of toArray()
. Maybe it is a matter of safety, but since the flatten method makes no assignments I thought it may be ok.
If it indees should be toArray()
then this PR could be only for some spelling in comments or closed.
Just a suggestion to use the native method of Arrays.