Jump to content

TIP: GetParameter is inefficient, here's a work around


Dewdman42
 Share

Recommended Posts

GetParameter Workaround

 

 

Summary

 

The GetParameter method in Scripter is a very expensive operation in Scripter. I measured it to be 60 times slower then a simple assignment (see below). This results in some CPU overhead that could effect CPU usage or even cause some dropped midi events when called often inside ProcessMIDI or HandleMIDI callbacks.

 

Solution

 

First, here is a simple solution. Copy and paste the following code into your Scripter script:

 

var GuiParameters = {
   data: [],
   set: function(id, val) {
       if(typeof id != "string") id = PluginParameters[id].name;
       this.data[id] = val;
   },
   get: function(id) {
       if(typeof id != "string") id = PluginParameters[id].name;
       if(this.data[id] == undefined) {
           this.data[id] = GetParameter(id);
       }
       return this.data[id];
   }
};
function ParameterChanged(id, val) {
   GuiParameters.set(id, val);
}

 

(Note, if your script is already utilizing the ParameterChanged callback, then add the single line of code to your version of that function)[/size]

 

The above will provide a new object called GuiParameters, which includes both a get and a set method. use these instead of GetParameter for obtaining the current GUI control values.

 

After that you can make calls to GuiParameters.get() to obtain GUI control values, 60 times faster. Like this:

 

function HandleMIDI(event) {
   // If GUI control 1 set to value of 2, then do this
   if( GuiParameters.get(1) == 2 ) {
       event.send();
   }
}

 

Deeper Explanation

 

I have been noticing that calls to GetParameter() can be rather costly in terms of CPU usage. Scripter is doing a lot of work under the covers with this call in order to obtain the current value of a Scripter GUI control. I set out to measure this, and found that GetParameter() requires as much as 60 times as much time to retrieve a GUI control value as it takes to assign a value from a variable. In other words, the first example below is 60 times slower then the second example:

 

var value = GetParameter(1);
var value = "some value";

You can test this yourself. The following script was used to measure this. Copy and paste the following script into Scripter and hit the RunScript button, then hit a key on your midi keyboard 10 times, to run the test, after 10 times it will display an average also:

 

var PluginParameters = [];

PluginParameters.push({
   name: "fieldOne",
   type: "menu",
   valueStrings: ["one","two","Three"],
   defaultValue: 0
});

PluginParameters.push({
   name: "fieldTwo",
   type: "menu",
   valueStrings: ["one","two","Three"],
   defaultValue: 1
});

PluginParameters.push({
   name: "fieldTwo",
   type: "menu",
   valueStrings: ["one","two","Three"],
   defaultValue: 1
});

var testCount=0;
var results = [];

function HandleMIDI(event) {

   var start = Date.now();
   for(i=0;i<10000;i++) {
       var val = GetParameter(1);
   }
   var end = Date.now();
   var time = end-start;
   
   //Trace("1000 iterations in "+ time +" ms");
   console.log("Time Per Op(GetParameter): "+time/10000+ " ms");

   results[testCount] = {};
   results[testCount].getParam = time/10000;
   
   var start = Date.now();
   for(i=0;i<10000;i++) {
       var val = GuiParameters.get(1);
   }
   var end = Date.now();
   var time = end-start;

    console.log("Time Per Op(assign): "+time/10000+ " ms");
    
    results[testCount].assign = time/10000;
    testCount++;
 
}

function Idle() {
   if(testCount==20) { 
       var gsum = 0;
       var asum = 0;
       for(var i=0;i<testCount;i++) {
            gsum += results[i].getParam;
            asum += results[i].assign;
       }
       
       var gavg = gsum/testCount;
       var aavg = asum/testCount;
       
       console.log("Average GetParameter Op Time = "+gavg+ " ms");
       console.log("Average Assign Op Time = "+aavg+" ms");
       console.log("GetParameter is "+gavg/aavg+" times slower");
   }
   console.flush();
}

var GuiParameters = {
   data: [],
   set: function(id, val) {
       this.data[id] = val;
   },
   get: function(id) {
       if(this.data[id] == undefined) {
           this.data[id] = GetParameter(id);
       }
       return this.data[id];
   }
};
function ParameterChanged(id, val) {
   GuiParameters.set(id, val);
}

var console = {
   maxFlush: 20,
   buffer: [],
   log: function(msg) {
       this.buffer.push(msg);
   },
   flush: function() {
       var i=0;
       while(i<=this.maxFlush && this.buffer.length>0) {
           Trace(this.buffer.shift());
           i++;
       }
   }
};
Average GetParameter Op Time = 0.016355 ms
Average Assign Op Time = 0.00026999999999999995 ms
GetParameter is 60.57407407407409 times slower

As you can see above, GetParameter() is still able to retrieve GUI control values in considerably less than a millisecond, so if you are only doing this occasionally in your scripts, it won't matter at all. However if you write a script that is perhaps calling GetParameter quite often, then this could begin to impact CPU usage and/or cause event dropping to occur. Use the GuiParameter() workaround to avoid this problem.

Edited by Dewdman42

OSX 12.x (Monterey) on OpenCore - Logic Pro 10.7.4, VePro7, Mainstage3 - 5,1 MacPro 3.46ghz x 12 96gb ram

Link to comment
Share on other sites

  • 1 year later...
Thanx man!

LogicPro 10.7.4, MainStage 3.6,
MBPro 17", Core2Duo, 8G, OSX 10.12.6, MacPro, Xeon 6Cores, 64GB, OSX 10.16.1,
ULN8, MOTU MIDI TP-AV, C4, MCU Pro, KorgNano, Novation SLMkII, Several vintage gear
AAS, NI, Celemony, Spectrasonics, Korg, Arturia, etc..., PC, iPadPro 5th gen 12.9”(Duet D., V-Control & LogicRemote), AtariST(Notator SL),

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...