Skip to content

Conversation

dvd101x
Copy link
Collaborator

@dvd101x dvd101x commented Sep 6, 2025

Hi Jos,

This makes it faster to map multiple arrays or matrices (with broadcasting), by not creating the internally broadcasted matrices unless the callback specifically needs it.

About 4x faster when no index is needed, 3x faster when an index is needed and is the same when also the broadcasted arrays or matrices are needed.

image

develop

abs(genericMatrix)                               1.41 µs   ±0.13%
abs(array)                                       1.28 µs   ±0.24%
abs(numberMatrix)                                1.42 µs   ±0.22%
genericMatrix.map(abs)                           5.01 µs   ±0.19%
numberMatrix.map(abs)                            5.01 µs   ±0.17%
map(genericMatrix, abs)                          5.03 µs   ±0.19%
map(numberMatrix, abs)                           5.01 µs   ±0.19%
map(array, abs)                                  5.01 µs   ±0.20%
map(array, abs.signatures.number)                2.23 µs   ±0.26%
genericMatrix.map(abs.signatures.number)         1.80 µs   ±5.91%
numberMatrix.map(abs.signatures.number)          1.70 µs   ±0.24%
genericMatrix iterate                            7.46 µs   ±0.25%
map(rowMatrix, columnMatrix, multiCallback)     35.78 µs   ±0.25%
map(rowArray, columnArray, multiCallback)       29.32 µs   ±0.20%
map(rowMatrix, columnMatrix, multiCallback1)    40.34 µs   ±0.19%
map(rowArray, columnArray, multiCallback1)      34.08 µs   ±0.19%
map(rowMatrix, columnMatrix, multiCallback2)    40.48 µs   ±0.17%
map(rowArray, columnArray, multiCallback2)      34.28 µs   ±0.20%

this PR

abs(genericMatrix)                               1.44 µs   ±0.19%
abs(array)                                       1.32 µs   ±0.28%
abs(numberMatrix)                                1.43 µs   ±0.24%
genericMatrix.map(abs)                           5.01 µs   ±0.16%
numberMatrix.map(abs)                            4.98 µs   ±0.16%
map(genericMatrix, abs)                          4.98 µs   ±0.16%
map(numberMatrix, abs)                           4.99 µs   ±0.23%
map(array, abs)                                  5.05 µs   ±0.16%
map(array, abs.signatures.number)                2.21 µs   ±0.18%
genericMatrix.map(abs.signatures.number)         1.73 µs   ±0.55%
numberMatrix.map(abs.signatures.number)          1.75 µs   ±0.36%
genericMatrix iterate                            7.44 µs   ±0.24%
map(rowMatrix, columnMatrix, multiCallback)      6.87 µs   ±0.19%
map(rowArray, columnArray, multiCallback)        6.80 µs   ±0.21%
map(rowMatrix, columnMatrix, multiCallback1)    12.38 µs   ±0.20%
map(rowArray, columnArray, multiCallback1)      12.31 µs   ±0.20%
map(rowMatrix, columnMatrix, multiCallback2)    39.79 µs   ±0.20%
map(rowArray, columnArray, multiCallback2)      33.06 µs   ±0.17%

@josdejong
Copy link
Owner

That is a big improvement, thanks David! It adds quite some code but I think that is worth it, and the new code is not very complex.

One thought: the body of _mapMultiple is growing quite large. Is it possible to:

  1. move logic from _mapMultiple into _getTypedCallbackCase and _getCallbackCase?
  2. move the functions _getLimitedCallback, _getCallbackCase, and _getTypedCallbackCase outside of _mapMultiple?
  3. change callbackCase into a const like:
    const callbackCase = typed.isTypedFunction(multiCallback)
      ? _getTypedCallbackCase(...)
      : _getCallbackCase(...)
  4. on a side note: I know the variables and functions where already named like callbackCase, but maybe a name like callbackArgumentCount or callbackArgCount would be more explanatory?

@dvd101x
Copy link
Collaborator Author

dvd101x commented Sep 15, 2025

Thank you Jos!

I will address the individual points in the following days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants