GTCMT / DataToMusicAPI

MIT License
27 stars 5 forks source link

Speed of dtm.data() #17

Open taylorbf opened 7 years ago

taylorbf commented 7 years ago

Hey there Taka,

DTM is usually pretty speedy -- for example, .rep(1000) or .rep(10000) create a lot of data and resolve in <10ms.

But I've noticed measurable delays when creating multiple dtm.arrays. For example --

    for (var i=0;i<1000;i++) {
         dtm.data(0)
    }

takes about 400ms to resolve for me, which is quite a bit of time, actually!

I know this is because creating a new dtm.array involves creating many new variables in different scopes, a lot of traversal, looping, etc.

But I wonder if you have advice on any way to make this take less time. Are there extensions of the dtm.array class which are rarely used, or disposable? Is there a way to create a "lightweight" dtm array with only the core methods? Or do you have ideas about an aspect of the code that might be causing the delay? I may do some hunting as well. : )

I ask because I am using dtm to create melodic patterns that are looped indefinitely. They use randomness so they need to be re-evaluated upon each loop. Therefore, I find myself creating a lot dtm arrays quite rapidly.

Sorry to keep bugging you. : ) This is not a time sensitive question -- respond at your liesure.

Project is going great. Thank you!

ttsuchiya commented 7 years ago

Thanks for reporting, Ben. I just profiled with the above code and there doesn't seem to be a specific culprit for the slow down (e.g., creating typed array can be slow). So it's maybe the problem of general implementation. One thing that might help is using prototypal functions than assigning anonymous functions to the properties, since the latter creates new function objects every time we instantiate a dtm.data... I'll see if I can refactor during the winter break.

taylorbf commented 7 years ago

Ah, OK.

Don't feel like you have to do a full refactor just because of me!

I'll keep investigating this a bit too and report back. Even creating 10000 float32arrays only takes about 15ms. But it may be that iterating through them and rewriting them takes more time.

I expect that part of my specific issue is that DTM is a broad and powerful lib, and I'm just using a small subset of its features. So my guess is that the best solution is to fork it and pare it down to the specific features that I need.

But I'll let you know. Thanks for your thoughts as always. : )

taylorbf commented 7 years ago

If it helps, I think about 1/2 of the time is spent on fnList.forEach().

I'm guessing that this applies dtm.array methods to any blocks that might exist in a dtm.array. Still trying to figure it out. : )

Anyway, if you're optimizing later, might be a good place to start. Not positive, but perhaps it is not necessary to run unless the array is blocked?

I learned so much reading through your array methods! So many cool things you can do. 👍

ttsuchiya commented 7 years ago

I refactored the data class to use prototypal functions instead of anonymous functions as object property that were created every time a dtm.data was created. Instantiation should be multiple times faster now. Also, it now allows augmenting with custom functions this way:

dtm.data.augment({
  aliases: { name1: ['alias1', 'alias2'], name2: etc. },
  name1: function (args) {
    this // data object
    this.val // raw (Float32Array) values
    this.length // array size
    return this; // this will allow method chaining
  },
  name2: etc.
})