gl-matrix
gl-matrix copied to clipboard
[Typescript] Possibility to restrict types to Float32Array only
Is it somehow possible to allow gl-matrix
to use only Float32Array
, disallowing any usage of normal js arrays?
Or maybe instead drop Float32Array
from types? They are less performant, and they can cause some type issues.
Example:
const va: vec3[] = [];
va.push([1, 2, 3]);
const f = va.flat(); // const f: (number | Float32Array)[]
@tsumo That's a bit more complicated than it would appear at first. Yes, Float32Arrays
are slower to instantiate, however gl-matrix is designed to work with WebGL (and WebGPU). When passing data to WebGL, it's preferable to pass it as a Float32Array
[1].
Here is a bit more regarding that https://github.com/toji/gl-matrix/issues/359
[1] Well, at least this used to be the case. For current browsers, I honestly don't have any performance figures. If you want to try to benchmark this, please do go ahead. I'd love to have some
@tsumo I'd prefer to drop everything else, but to keep only Float32Array instead. There is just no point in using plain js arrays while working with WebGL. Typed arrays require no conversion when working with WebGL functions, multiple Float32Array can be created with padding on a single array buffer and uploaded to video memory at once, typed arrays can be easily moved between threads, etc. Plain JS arrays require lots of conversions on every mentioned step, so they are actually slower. More of that, mixing them with typed arrays makes them even slower because if you create a vector/matrix whatever using gl-matrix, it will give you a typed array, so all gl-matrix functions at some point in application can receive either typed array, or plain js array, so it makes them polymorphic, and they become slower than monomorphic. If performance a must-have thing, typed arrays should not be ever mixed with plain js arrays, that's why this feature request was made.
I see. Then type issues could be resolved with some kind of initializer factory
const glmTyped = initializeTyped();
const v1 = glmTyped.vec3.create(); // v1: Float32Array
const glmArray = initializeArray();
const v2 = glmArray.vec3.create(); // v2: [number, number, number]
This change should not require any duplication of main library code, since it already works with both typed and untyped arrays.
such a factory has different issues, like the inability to tree-shake (I don't really care about this particular case because my assets are much bigger than JS bundle) but for some, it's an issue anyway. more of that, such a factory is only useful when you use only one version of the storage array, if you used both, even created via factory, performance will drop anyway. So I'd solve it on a type level, not a code. not sure how exactly though
Perhaps you should into lodash: https://lodash.com/