tl;dr
It doesn’t matter and any gains you could gain are meaningless and much smaller than gains you’d get from anything else. Use whatever you like best and use it always.
Below is a verbose answer with some well-meaning-but-might-sound-serious jabs about microoptimization.
It doesn’t matter.
Any gain in speed is insignificant.
It’s increasing your car mileage by emptying the ashtray.
But I know how it is to microoptimize, thank goodness I grew out of it as a programmer. So here are the results of my tests:
Ran 3 tests, 1000000 times each, everything was repeated 50 times
##### [all[current]] #####
Total time: 42685ms
Average repeat (1000000 runs): 853.7000ms
Average test run: 0.0009ms
##### [<currentTiddler>] #####
Total time: 29842ms
Average repeat (1000000 runs): 596.8400ms
Average test run: 0.0006ms
##### [{!!title}] #####
Total time: 34223ms
Average repeat (1000000 runs): 684.4600ms
Average test run: 0.0007ms
MEANINGLESS I tell you
- A typical computer will have refresh rate of 60 Hz, which gives you 16 milliseconds per frame. Regardless of the method, you need to use this filter operator more than thousand times to get close to it taking a full millisecond.
- Go to my plugin showcase, take a look at the Advanced Performance footer, click on the search bar. On the same computer are ran the above tests just switching the focus takes 12ms. That’s 12 000, twelve hundred, retrievals of current tiddler.
- Optimize anything else because, I can bet you money, anything else you optimize will give you an order of magnitude better results than this.
But if you insist:
-
[<currentTiddler>]
consistently gives the best time. Makes sense because it’s just a variable lookup.
-
[{!!title}]
consistently is in the second place. Makes sense because it does three things:
- Variable lookup.
- Tiddler retrieval.
- Reading the field from the tiddler.
-
[all[tiddler]]
consistently gives the worst time. Makes sense because it does four things:
- Run the filter operator.
- Do the three things
[{!!title}]
has to do.
It still doesn’t matter
Here is the code if you’d like to try it yourself. I made sure to prepare the fake data such that each filter does return test
:
(function run(){
const attempts = 1000000;
const repeats = 50;
const attempt = function(callback) {
const start = Date.now();
for (let i = 0; i < attempts; i++) {
callback();
}
const end = Date.now();
const delta = end - start;
return delta;
}
const getVariableFauxWidget = (name, value) => {
return {
getVariable: function (name_) {
if (name_ === name) {
return value;
}
return "";
}
}
}
const tempTiddler = new $tw.Tiddler({title: 'test'});
const filter = (f) => {
$tw.wiki.filterTiddlers(f, getVariableFauxWidget('currentTiddler', 'test', (callback) => {
callback(tempTiddler, 'test');
}));
}
const tests = [
["[all[current]]", () => attempt(() => {filter('[all[current]]');})],
["[<currentTiddler>]", () => attempt(() => {filter('[<currentTiddler>]');})],
["[{!!title}]", () => attempt(() => {filter('[{!!title}]');})],
]
const results = tests.map(x => []);
for (let i = 0; i < repeats; i++) {
for (let j = 0; j < tests.length; j++) {
results[j].push(tests[j][1]());
}
console.log(`Tests done in ${(100*i/repeats).toFixed(2)}%`)
}
console.log(`Finished running tests!`)
console.log(`Ran ${tests.length} tests, ${attempts} times each, everything was repeated ${repeats} times`);
for (let i = 0; i < tests.length; i++) {
const [name] = tests[i];
const testResults = results[i];
const totalRuntime = testResults.reduce((total, next) => total + next);
const totalRuns = attempts * repeats;
const averageRepeat = totalRuntime / repeats;
const averageRun = totalRuntime / totalRuns;
console.log(`##### ${name} #####`);
console.log(`Total time: ${totalRuntime.toFixed(0)}ms`);
console.log(`Average repeat (${attempts} runs): ${averageRepeat.toFixed(4)}ms`);
console.log(`Average test run: ${averageRun.toFixed(4)}ms`);
}
})()