Add support to benchmark the dynamic filtering pane

From uBO's dev console, type:
- `µBlock.sessionFirewall.benchmark();`

Keep in mind that it's the temporary ruleset being benchmarked.
This commit is contained in:
Raymond Hill 2019-02-19 10:46:33 -05:00
parent 3ee25537a1
commit 928ab91ab8
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
3 changed files with 116 additions and 59 deletions

View File

@ -528,7 +528,7 @@ Matrix.prototype.removeFromRuleParts = function(parts) {
/******************************************************************************/
var magicId = 1;
const magicId = 1;
Matrix.prototype.toSelfie = function() {
return {
@ -546,6 +546,35 @@ Matrix.prototype.fromSelfie = function(selfie) {
/******************************************************************************/
Matrix.prototype.benchmark = function() {
µBlock.loadBenchmarkDataset().then(requests => {
if ( Array.isArray(requests) === false || requests.length === 0 ) {
console.info('No requests found to benchmark');
return;
}
console.info(`Benchmarking sessionFirewall.evaluateCellZY()...`);
const fctxt = µBlock.filteringContext.duplicate();
const t0 = self.performance.now();
for ( const request of requests ) {
fctxt.setURL(request.url);
fctxt.setTabOriginFromURL(request.frameUrl);
fctxt.setType(request.cpt);
this.evaluateCellZY(
fctxt.getTabHostname(),
fctxt.getHostname(),
fctxt.type
);
}
const t1 = self.performance.now();
const dur = t1 - t0;
console.info(`Evaluated ${requests.length} requests in ${dur.toFixed(0)} ms`);
console.info(`\tAverage: ${(dur / requests.length).toFixed(3)} ms per request`);
});
return 'ok';
};
/******************************************************************************/
return Matrix;
/******************************************************************************/

View File

@ -2690,74 +2690,20 @@ FilterContainer.prototype.getFilterCount = function() {
/******************************************************************************/
// The requests.json.gz file can be downloaded from:
// https://cdn.cliqz.com/adblocking/requests_top500.json.gz
//
// Which is linked from:
// https://whotracks.me/blog/adblockers_performance_study.html
//
// Copy the file into ./tmp/requests.json.gz
//
// If the file is present when you build uBO using `make-[target].sh` from
// the shell, the resulting package will have `./assets/requests.json`, which
// will be looked-up by the method below to launch a benchmark session.
//
// From uBO's dev console, launch the benchmark:
// µBlock.staticNetFilteringEngine.benchmark();
//
// The advanced setting `consoleLogLevel` must be set to `info` to see the
// results in uBO's dev console, see:
// https://github.com/gorhill/uBlock/wiki/Advanced-settings#consoleloglevel
//
// The usual browser dev tools can be used to obtain useful profiling
// data, i.e. start the profiler, call the benchmark method from the
// console, then stop the profiler when it completes.
//
// Keep in mind that the measurements at the blog post above where obtained
// with ONLY EasyList. The CPU reportedly used was:
// https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i7-6600U+%40+2.60GHz&id=2608
//
// Rename ./tmp/requests.json.gz to something else if you no longer want
// ./assets/requests.json in the build.
FilterContainer.prototype.benchmark = function() {
new Promise(resolve => {
console.info(`Loading benchmark dataset...`);
const url = vAPI.getURL('/assets/requests.json');
µb.assets.fetchText(url, details => {
if ( details.error !== undefined ) {
console.info(`Not found: ${url}`);
resolve();
return;
}
console.info(`Parsing benchmark dataset...`);
const requests = [];
const lineIter = new µb.LineIterator(details.content);
while ( lineIter.eot() === false ) {
let request;
try {
request = JSON.parse(lineIter.next());
} catch(ex) {
}
if ( request instanceof Object === false ) { continue; }
if ( !request.frameUrl || !request.url ) { continue; }
requests.push(request);
}
resolve(requests);
});
}).then(requests => {
µb.loadBenchmarkDataset().then(requests => {
if ( Array.isArray(requests) === false || requests.length === 0 ) {
console.info('No requests found to benchmark');
return;
}
console.info(`Benchmarking...`);
const fctxt = µb.filteringContext;
console.info(`Benchmarking staticNetFilteringEngine.matchString()...`);
const fctxt = µb.filteringContext.duplicate();
const t0 = self.performance.now();
for ( const request of requests ) {
fctxt.setURL(request.url);
fctxt.setDocOriginFromURL(request.frameUrl);
fctxt.setType(request.cpt);
void this.matchString(fctxt);
this.matchString(fctxt);
}
const t1 = self.performance.now();
const dur = t1 - t0;

View File

@ -605,3 +605,85 @@
return rem === 0 ? size : size + rem - 1;
},
};
/******************************************************************************/
// The requests.json.gz file can be downloaded from:
// https://cdn.cliqz.com/adblocking/requests_top500.json.gz
//
// Which is linked from:
// https://whotracks.me/blog/adblockers_performance_study.html
//
// Copy the file into ./tmp/requests.json.gz
//
// If the file is present when you build uBO using `make-[target].sh` from
// the shell, the resulting package will have `./assets/requests.json`, which
// will be looked-up by the method below to launch a benchmark session.
//
// From uBO's dev console, launch the benchmark:
// µBlock.staticNetFilteringEngine.benchmark();
//
// The advanced setting `consoleLogLevel` must be set to `info` to see the
// results in uBO's dev console, see:
// https://github.com/gorhill/uBlock/wiki/Advanced-settings#consoleloglevel
//
// The usual browser dev tools can be used to obtain useful profiling
// data, i.e. start the profiler, call the benchmark method from the
// console, then stop the profiler when it completes.
//
// Keep in mind that the measurements at the blog post above where obtained
// with ONLY EasyList. The CPU reportedly used was:
// https://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i7-6600U+%40+2.60GHz&id=2608
//
// Rename ./tmp/requests.json.gz to something else if you no longer want
// ./assets/requests.json in the build.
µBlock.loadBenchmarkDataset = (function() {
let datasetPromise;
let ttlTimer;
return function() {
if ( ttlTimer !== undefined ) {
clearTimeout(ttlTimer);
ttlTimer = undefined;
}
vAPI.setTimeout(( ) => {
ttlTimer = undefined;
datasetPromise = undefined;
}, 60000);
if ( datasetPromise !== undefined ) {
return datasetPromise;
}
datasetPromise = new Promise(resolve => {
console.info(`Loading benchmark dataset...`);
const url = vAPI.getURL('/assets/requests.json');
µBlock.assets.fetchText(url, details => {
if ( details.error !== undefined ) {
datasetPromise = undefined;
console.info(`Not found: ${url}`);
resolve();
return;
}
console.info(`Parsing benchmark dataset...`);
const requests = [];
const lineIter = new µBlock.LineIterator(details.content);
while ( lineIter.eot() === false ) {
let request;
try {
request = JSON.parse(lineIter.next());
} catch(ex) {
}
if ( request instanceof Object === false ) { continue; }
if ( !request.frameUrl || !request.url ) { continue; }
requests.push(request);
}
resolve(requests);
});
});
return datasetPromise;
};
})();