I just want to add to this thread token properties are always going to be faster than using JSON objects -- for 1.3 at least. This is because of the following reasons.
- JSON objects under certain conditions (reading/writing from/to token properties) requires conversion from one internal representation to another.
- MapTool supports storing JSON objects as string representations -- this is one of the main points behind JSON -- and strings are immutable in MapTool script, therefore JSON objects need to be immutable.
It has nothing to do with pass by value/references.When using [macro(): ] calls passing a JSON object (or property, or number) is essentially the following code in the MapTool.
Code: Select all
newScope.put("macro.args", args);
Which creates a new variable in the new scope.
If you have your JSON object inside of a token property (say for example WeaponsList) and do the following
Code: Select all
[c(100), code: {
[macro("blah@lib:token"): WeponList]
}]
You will take a internal conversion hit from token property representation to internal variable representation on each and every time through the loop. You could easily speed this up by doing the following for large JSON object.
Code: Select all
[wList = WeaponList]
[c(100), code: {
[macro("blah@lib:token"): wList]
}]
User defined functions occur differently. User defined functions in reality are not function calls. What they do is create a new string that is passed to the parser, so when you have a large argument this parsing takes extra time -- this is not to be confused with copying on pass by value because this is not what it is. So there are two solutions to this problem, keep your arguments small or use [macro(): ], but again be careful about "invisible" conversions when placing the token property directly in the call.
While allowing JSON objects to be mutable would solve several of the speed issues with modifying JSON objects it is not possible to make them mutable in all cases which means you end up with a large list of exceptions where JSON objects would still be immutable. Also supporting mutable JSON objects withing user defined functions would require a
lot more processing than is currently done and significantly slow down calls to user defined functions.
In 1.4 there is a large opportunity for scripting performance and the two things that will provide the greatest performance are
JavaScript
This is not because JavaScript is an inherently faster language, but because of the way that parsing currently occurs in MapTool. The JavaScript engine will parse all input once and generate an intermediate code that it can process a lot faster.
The way MapTool currently works there is a Parser module (not part of the MapTool code) that parses all text and generates intermediate code that is faster to process, but this only parses/executes the text that MapTool passes to it. The MapTool input scanner breaks up macros and sends then essentially line by line to the Parser module, so when you loop you re parse the same text over and over and over.
JSON improvements
This has nothing to do with the implementation of JSON in JavaScript itself, but in 1.4 hopefully the parts of MapTool that expect strings and only strings to be stored in token properties can be fixed so that they wont bomb out when something other than a string is stored, this way there will be no conversion hit when moving JSON objects to and from token properties.