Skip to content

Commit

Permalink
Add support to benchmark the dynamic filtering pane
Browse files Browse the repository at this point in the history
From uBO's dev console, type:
- `µBlock.sessionFirewall.benchmark();`

Keep in mind that it's the temporary ruleset being benchmarked.
  • Loading branch information
gorhill committed Feb 19, 2019
1 parent 3ee2553 commit 928ab91
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 59 deletions.
31 changes: 30 additions & 1 deletion src/js/dynamic-net-filtering.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ Matrix.prototype.removeFromRuleParts = function(parts) {

/******************************************************************************/

var magicId = 1;
const magicId = 1;

Matrix.prototype.toSelfie = function() {
return {
Expand All @@ -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;

/******************************************************************************/
Expand Down
62 changes: 4 additions & 58 deletions src/js/static-net-filtering.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
82 changes: 82 additions & 0 deletions src/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
})();

0 comments on commit 928ab91

Please sign in to comment.