Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve engine events to expose internal workflow #3881

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

seia-soto
Copy link
Member

fixes #3876

Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few things to address:

  1. To have a better overview we should also emit information of the exceptions (unHide), similarly to how it is being done for the network matches.
  2. how about we have one new event, lets call it match that would fire for both network and cosmetic filters. It's params should look alike for both types. (don't remove old event, they important for backwards compatibility)

I see it like this:

const context = { tabId: 1, frameId: 2 };
engine.getCosmeticsFilters(oldParams, withMetadata, context);
engine.match(request, withMetadata, context);
engine.on('match', (context, result) => {
  console.log(context, result.match, result.exception, result.metadata); 
});

Notice withMetadata for getCosmeticsFilters this is another capability to remember about. The result for the cosmetic filters should include the metadata in the same way the network result does.

packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
@seia-soto
Copy link
Member Author

@remusao I'd like to get a feedback about the way passing "context" to matching functions. It might help a lot for extension developers often used to involve tabId.

@chrmod This is actually an off-topic but if we involve devTools API, we can avoid involving tabId. The devtools apis are already provided in scope of the page, so we don't need to take care about the tabs.

Passing an external context can solve many complex situations but I'd like to go simple as possible. For example, we could decorate the passed Request object and many other things. Also, we're already passing request as an argument for network filter matches.

console.log('extended-rule-matched', rule, context);
});

blocker.on('style-rule-matched', (rule, context) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could make it clearer in the naming that this is a hostname-based march of a cosmetic rule. Also, that it does not mean it marched in the page, just that it was selected by the engine as a candidate to be injected (I think it’s important to make this clear to avoid confusion)

@chrmod chrmod added the PR: New Feature 🚀 Increment minor version when merged label Apr 15, 2024
packages/adblocker-playwright-example/index.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need that many new events. How about we introduce one filter-matched which would emit:

  • a filter, cosmetic or network
  • a function name used to acquire the filter, like match, getHtmlFilters, getCosmeticsFilters
  • function arguments, which can include additional info like the context: any. For network filters it is most important to get the request.

Additionally, would like to set a naming convention for the public interfaces for the filters. Sometimes we call those things rules (for instance in context of Cosmetic bucket), but on the interface level I would strony suggest we always call both network and cosmetic "rule" with a name of filters.
This will be a contrast to the DNR, where after conversion the filters become the rules.

@seia-soto
Copy link
Member Author

In the last changes, the events were narrowed down to two: filter-matched and filter-excluded. Note that this idea was built top on the idea of adblocker debugger ui implementation.

Also, the commit addresses the followings:

  • Proper naming of EngineEventContext (renamed to MatchingContext): this variable name is expected to cause a lot of confusions.
  • MatchingContext was updated to the union type with a proper enum typing to support the sole and integrated event kinds: filter-matched and filter-excluded.
  • The additional argument can be passed to methods was renamed to reference instead of context to reduce confusion.

@seia-soto seia-soto changed the title feat: emit cosmetic rules on match Improve engine events to expose internal workflow Apr 30, 2024
Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add filter-matched for network filters as well? that would be in engine.match and engine.matchAll

packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Show resolved Hide resolved
packages/adblocker/src/events.ts Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like while we develop this feature it started to change direction. All good, but it also got a bit complex. Lets try to simplify a bit before moving forward.

To recap the goal: We want to introduce new events that would allow us to implement a logger that is able to list matched filters and exceptions in a context of a given tab.

packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
@@ -1035,6 +1195,8 @@ export default class FilterEngine extends EventEmitter<

// Emit events if we found a match
if (result.exception !== undefined) {
this.emit('filter-matched', result.exception, context);

this.emit('request-whitelisted', request, result);
} else if (result.redirect !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we emit redirects as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is treated as a normal filter (result.filter) before being registered as result.redirect. The event should be triggered right after the filter match.

packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker-electron-example/index.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Show resolved Hide resolved
Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let me test it locally before merging.

@seia-soto seia-soto marked this pull request as ready for review May 15, 2024 04:32
Copy link
Collaborator

@remusao remusao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add unit tests for each of the event with cases where they should/shouldn't trigger?

Also, please do run the benchmark to validate that there isn't extra overhead with the additional data-structures we are creating on each call to engine matching functions.

packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks to @remusao comments I've realised that we should populate the reference in all the helper libraries, that is adblocker-webextension, adblocker-puppeteer, and adblocker-playwrights. If we wont, customers of those libraries wont be able to distinguish the source of events from getCosmeticsFilters so for examples in browsers, those events wont be useful.

@seia-soto seia-soto force-pushed the emit-cosmetic-filter-matches branch from d9c6b86 to ba99f8a Compare June 10, 2024 01:16
@seia-soto
Copy link
Member Author

Benchmarking results

seia-soto:emit-cosmetic-filter-matches

Details

cd ../.. && yarn install --immutable && yarn build
➤ YN0000: · Yarn 4.2.2
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 403ms

 Lerna (powered by Nx)   Running target build for 10 projects:

- @cliqz/adblocker
- @cliqz/adblocker-content
- @cliqz/adblocker-electron
- @cliqz/adblocker-electron-preload
- @cliqz/adblocker-extended-selectors
- @cliqz/adblocker-playwright
- @cliqz/adblocker-puppeteer
- @cliqz/adblocker-webextension
- @cliqz/adblocker-webextension-cosmetics
- @cliqz/adblocker-webextension-example



> @cliqz/adblocker-extended-selectors:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m161ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m23ms�[22m�[39m

> @cliqz/adblocker-content:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m114ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m9ms�[22m�[39m

> @cliqz/adblocker-electron-preload:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/preload.js�[22m → �[1m./dist/cjs/preload.cjs, ./dist/esm/preload.cjs�[22m...�[39m
�[32mcreated �[1m./dist/cjs/preload.cjs, ./dist/esm/preload.cjs�[22m in �[1m48ms�[22m�[39m

> @cliqz/adblocker-webextension-cosmetics:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m213ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1m@cliqz/adblocker-extended-selectors�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m11ms�[22m�[39m

> @cliqz/adblocker:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m975ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Mixing named and default exports�[39m�[22m
�[90mhttps://rollupjs.org/configuration-options/#output-exports�[39m
�[1mThe following entry modules are using named and default exports together:�[22m
dist/src/src/engine/bucket/cosmetic.js
dist/src/src/engine/engine.js
dist/src/src/engine/reverse-index.js
...and 5 other entry modules

Consumers of your bundle will have to use chunk.default to access their default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1m@cliqz/adblocker-extended-selectors�[22m (imported by "dist/src/src/filters/cosmetic.js")
�[1m@remusao/guess-url-type�[22m (imported by "dist/src/src/request.js")
�[1mtldts-experimental�[22m (imported by "dist/src/src/request.js")
�[1m@remusao/small�[22m (imported by "dist/src/src/resources.js")
�[1m@remusao/smaz�[22m (imported by "dist/src/src/compression.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m131ms�[22m�[39m

> @cliqz/adblocker-playwright:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.8s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m17ms�[22m�[39m

> @cliqz/adblocker-webextension:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.7s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m18ms�[22m�[39m

> @cliqz/adblocker-electron:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[1m�[33m(!) Missing shims for Node.js built-ins�[39m�[22m
Creating a browser bundle that depends on "node:module". You might need to include https://github.com/FredKSchott/rollup-plugin-polyfill-node
�[1m�[33m(!) Missing global variable name�[39m�[22m
�[90mhttps://rollupjs.org/configuration-options/#output-globals�[39m
Use "output.globals" to specify browser global variable names corresponding to external modules:
�[1mnode:module�[22m (guessing "node_module")
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.6s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1melectron�[22m (imported by "dist/src/adblocker.js")
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1mnode:module�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m13ms�[22m�[39m

> @cliqz/adblocker-puppeteer:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.6s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m20ms�[22m�[39m

> @cliqz/adblocker-webextension-example:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/background.js�[22m → �[1m./dist/background.iife.js�[22m...�[39m
�[32mcreated �[1m./dist/background.iife.js�[22m in �[1m376ms�[22m�[39m
�[36m
�[1m./dist/src/content-script.js�[22m → �[1m./dist/content-script.iife.js�[22m...�[39m
�[32mcreated �[1m./dist/content-script.iife.js�[22m in �[1m22ms�[22m�[39m



 Lerna (powered by Nx)   Successfully ran target build for 10 projects


yarn install --immutable
➤ YN0000: · Yarn 4.2.2
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 82ms
NODE_ENV=production node run.js url 
* url
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (0 samples): n/a
Avg deserialization time (0 samples): n/a
Serialized size: n/a
List parsing time: 10.834 μs
Initialization time: 445.792 μs

Total requests: 233,347
Total match: 233,347
Total no match: 0

Number of samples: 233,347
Min match: 0.375 μs
Max match: 2,036.333 μs
Avg match: 0.767 μs

Number of samples: 0
Min no match: n/a
Max no match: n/a
Avg no match: n/a

Number of samples: 233,347
Min (total): 0.375 μs
Max (total): 2,036.333 μs
Avg (total): 0.767 μs

NODE_ENV=production node run.js tldts 
* tldts
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (0 samples): n/a
Avg deserialization time (0 samples): n/a
Serialized size: n/a
List parsing time: 9.709 μs
Initialization time: 3,102.958 μs

Total requests: 233,347
Total match: 233,347
Total no match: 0

Number of samples: 233,347
Min match: 0.25 μs
Max match: 2,490.417 μs
Avg match: 0.574 μs

Number of samples: 0
Min no match: n/a
Max no match: n/a
Avg no match: n/a

Number of samples: 233,347
Min (total): 0.25 μs
Max (total): 2,490.417 μs
Avg (total): 0.574 μs

NODE_ENV=production node run.js cliqz 
* cliqz
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 190.044 μs
Avg deserialization time (100 samples): 22.983 μs
Serialized size: 1,866 KiB
List parsing time: 115,573.042 μs
Initialization time: 21,434.958 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.125 μs
Max match: 1,847.125 μs
Avg match: 6.277 μs

Number of samples: 139,053
Min no match: 1.25 μs
Max no match: 4,634.208 μs
Avg no match: 8.468 μs

Number of samples: 233,347
Min (total): 1.125 μs
Max (total): 4,634.208 μs
Avg (total): 7.583 μs

NODE_ENV=production node run.js ublock 
* ublock
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 2,834.377 μs
Avg deserialization time (100 samples): 13.893 μs
Serialized size: 1 KiB
List parsing time: 145,784 μs
Initialization time: 23,347.333 μs

Total requests: 233,347
Total match: 98,549
Total no match: 134,798

Number of samples: 98,549
Min match: 0.375 μs
Max match: 420.375 μs
Avg match: 2.901 μs

Number of samples: 134,798
Min no match: 0.666 μs
Max no match: 1,834.459 μs
Avg no match: 2.616 μs

Number of samples: 233,347
Min (total): 0.375 μs
Max (total): 1,834.459 μs
Avg (total): 2.737 μs

NODE_ENV=production node run.js adblockplus 
* adblockplus
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 4,035.858 μs
Avg deserialization time (100 samples): 53,940.517 μs
Serialized size: 1,384 KiB
List parsing time: 143,560.375 μs
Initialization time: 18,403.458 μs

Total requests: 233,347
Total match: 94,266
Total no match: 139,081

Number of samples: 94,266
Min match: 1.041 μs
Max match: 1,655.833 μs
Avg match: 10.849 μs

Number of samples: 139,081
Min no match: 1 μs
Max no match: 2,729.708 μs
Avg no match: 11.52 μs

Number of samples: 233,347
Min (total): 1 μs
Max (total): 2,729.708 μs
Avg (total): 11.249 μs

NODE_ENV=production node run.js brave 
* brave
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 25,181.505 μs
Avg deserialization time (100 samples): 30,165.232 μs
Serialized size: 3,508 KiB
List parsing time: 95,499.667 μs
Initialization time: 5,298 μs

Total requests: 233,347
Total match: 94,292
Total no match: 139,055

Number of samples: 94,292
Min match: 1.209 μs
Max match: 412.583 μs
Avg match: 7.059 μs

Number of samples: 139,055
Min no match: 1.292 μs
Max no match: 11,677.75 μs
Avg no match: 15.673 μs

Number of samples: 233,347
Min (total): 1.209 μs
Max (total): 11,677.75 μs
Avg (total): 12.192 μs

NODE_ENV=production node run.js adblockfast 
* adblockfast
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 333.923 μs
Avg deserialization time (100 samples): 339.715 μs
Serialized size: 127 KiB
List parsing time: 3,092.292 μs
Initialization time: 3,706.542 μs

Total requests: 233,347
Total match: 80,912
Total no match: 152,435

Number of samples: 80,912
Min match: 0.25 μs
Max match: 228.875 μs
Avg match: 2.036 μs

Number of samples: 152,435
Min no match: 0.875 μs
Max no match: 6,659,647.25 μs
Avg no match: 46.48 μs

Number of samples: 233,347
Min (total): 0.25 μs
Max (total): 6,659,647.25 μs
Avg (total): 31.069 μs

master

Details
cd ../.. && yarn install --immutable && yarn build
➤ YN0000: · Yarn 4.2.2
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 402ms

 Lerna (powered by Nx)   Running target build for 10 projects:

- @cliqz/adblocker
- @cliqz/adblocker-content
- @cliqz/adblocker-electron
- @cliqz/adblocker-electron-preload
- @cliqz/adblocker-extended-selectors
- @cliqz/adblocker-playwright
- @cliqz/adblocker-puppeteer
- @cliqz/adblocker-webextension
- @cliqz/adblocker-webextension-cosmetics
- @cliqz/adblocker-webextension-example



> @cliqz/adblocker-extended-selectors:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m161ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m22ms�[22m�[39m

> @cliqz/adblocker-content:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m114ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m10ms�[22m�[39m

> @cliqz/adblocker-electron-preload:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/preload.js�[22m → �[1m./dist/cjs/preload.cjs, ./dist/esm/preload.cjs�[22m...�[39m
�[32mcreated �[1m./dist/cjs/preload.cjs, ./dist/esm/preload.cjs�[22m in �[1m41ms�[22m�[39m

> @cliqz/adblocker-webextension-cosmetics:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m193ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1m@cliqz/adblocker-extended-selectors�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m9ms�[22m�[39m

> @cliqz/adblocker:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m935ms�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Mixing named and default exports�[39m�[22m
�[90mhttps://rollupjs.org/configuration-options/#output-exports�[39m
�[1mThe following entry modules are using named and default exports together:�[22m
dist/src/src/engine/bucket/cosmetic.js
dist/src/src/engine/engine.js
dist/src/src/engine/reverse-index.js
...and 5 other entry modules

Consumers of your bundle will have to use chunk.default to access their default export, which may not be what you want. Use `output.exports: "named"` to disable this warning.
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1m@remusao/guess-url-type�[22m (imported by "dist/src/src/request.js")
�[1mtldts-experimental�[22m (imported by "dist/src/src/request.js")
�[1m@cliqz/adblocker-extended-selectors�[22m (imported by "dist/src/src/filters/cosmetic.js")
�[1m@remusao/small�[22m (imported by "dist/src/src/resources.js")
�[1m@remusao/smaz�[22m (imported by "dist/src/src/compression.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m146ms�[22m�[39m

> @cliqz/adblocker-electron:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[1m�[33m(!) Missing shims for Node.js built-ins�[39m�[22m
Creating a browser bundle that depends on "node:module". You might need to include https://github.com/FredKSchott/rollup-plugin-polyfill-node
�[1m�[33m(!) Missing global variable name�[39m�[22m
�[90mhttps://rollupjs.org/configuration-options/#output-globals�[39m
Use "output.globals" to specify browser global variable names corresponding to external modules:
�[1mnode:module�[22m (guessing "node_module")
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.7s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1melectron�[22m (imported by "dist/src/adblocker.js")
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1mnode:module�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m33ms�[22m�[39m

> @cliqz/adblocker-playwright:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.7s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m12ms�[22m�[39m

> @cliqz/adblocker-webextension:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.7s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m12ms�[22m�[39m

> @cliqz/adblocker-puppeteer:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/adblocker.umd.min.js�[22m...�[39m
�[32mcreated �[1m./dist/adblocker.umd.min.js�[22m in �[1m1.6s�[22m�[39m
�[36m
�[1m./dist/src/adblocker.js�[22m → �[1m./dist/esm, ./dist/cjs�[22m...�[39m
�[1m�[33m(!) Unresolved dependencies�[39m�[22m
�[90mhttps://rollupjs.org/troubleshooting/#warning-treating-module-as-external-dependency�[39m
�[1mtldts-experimental�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker�[22m (imported by "dist/src/adblocker.js")
�[1m@cliqz/adblocker-content�[22m (imported by "dist/src/adblocker.js")
�[32mcreated �[1m./dist/esm, ./dist/cjs�[22m in �[1m11ms�[22m�[39m

> @cliqz/adblocker-webextension-example:build

�[1mloaded rollup.config.ts with warnings�[22m
�[1m�[33m(!) [plugin typescript] @rollup/plugin-typescript: Rollup 'sourcemap' option must be set to generate source maps.�[39m�[22m
�[36m
�[1m./dist/src/background.js�[22m → �[1m./dist/background.iife.js�[22m...�[39m
�[32mcreated �[1m./dist/background.iife.js�[22m in �[1m374ms�[22m�[39m
�[36m
�[1m./dist/src/content-script.js�[22m → �[1m./dist/content-script.iife.js�[22m...�[39m
�[32mcreated �[1m./dist/content-script.iife.js�[22m in �[1m21ms�[22m�[39m



 Lerna (powered by Nx)   Successfully ran target build for 10 projects


yarn install --immutable
➤ YN0000: · Yarn 4.2.2
➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done in 0s 84ms
NODE_ENV=production node run.js url 
* url
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (0 samples): n/a
Avg deserialization time (0 samples): n/a
Serialized size: n/a
List parsing time: 12 μs
Initialization time: 454.708 μs

Total requests: 233,347
Total match: 233,347
Total no match: 0

Number of samples: 233,347
Min match: 0.416 μs
Max match: 2,483.084 μs
Avg match: 0.777 μs

Number of samples: 0
Min no match: n/a
Max no match: n/a
Avg no match: n/a

Number of samples: 233,347
Min (total): 0.416 μs
Max (total): 2,483.084 μs
Avg (total): 0.777 μs

NODE_ENV=production node run.js tldts 
* tldts
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (0 samples): n/a
Avg deserialization time (0 samples): n/a
Serialized size: n/a
List parsing time: 8.75 μs
Initialization time: 4,164.917 μs

Total requests: 233,347
Total match: 233,347
Total no match: 0

Number of samples: 233,347
Min match: 0.25 μs
Max match: 2,323.459 μs
Avg match: 0.57 μs

Number of samples: 0
Min no match: n/a
Max no match: n/a
Avg no match: n/a

Number of samples: 233,347
Min (total): 0.25 μs
Max (total): 2,323.459 μs
Avg (total): 0.57 μs

NODE_ENV=production node run.js cliqz 
* cliqz
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 249.93 μs
Avg deserialization time (100 samples): 65.808 μs
Serialized size: 1,866 KiB
List parsing time: 100,773.166 μs
Initialization time: 20,355.791 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.125 μs
Max match: 1,746.667 μs
Avg match: 6.154 μs

Number of samples: 139,053
Min no match: 1.25 μs
Max no match: 3,442.042 μs
Avg no match: 8.364 μs

Number of samples: 233,347
Min (total): 1.125 μs
Max (total): 3,442.042 μs
Avg (total): 7.471 μs

NODE_ENV=production node run.js ublock 
* ublock
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 2,830.188 μs
Avg deserialization time (100 samples): 14.288 μs
Serialized size: 1 KiB
List parsing time: 144,020.333 μs
Initialization time: 24,123.792 μs

Total requests: 233,347
Total match: 98,549
Total no match: 134,798

Number of samples: 98,549
Min match: 0.375 μs
Max match: 1,597.291 μs
Avg match: 2.914 μs

Number of samples: 134,798
Min no match: 0.666 μs
Max no match: 780.958 μs
Avg no match: 2.576 μs

Number of samples: 233,347
Min (total): 0.375 μs
Max (total): 1,597.291 μs
Avg (total): 2.719 μs

NODE_ENV=production node run.js adblockplus 
* adblockplus
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 3,836.546 μs
Avg deserialization time (100 samples): 51,382.196 μs
Serialized size: 1,384 KiB
List parsing time: 138,572.375 μs
Initialization time: 19,624 μs

Total requests: 233,347
Total match: 94,266
Total no match: 139,081

Number of samples: 94,266
Min match: 1.041 μs
Max match: 1,746 μs
Avg match: 10.807 μs

Number of samples: 139,081
Min no match: 1 μs
Max no match: 2,584.584 μs
Avg no match: 11.234 μs

Number of samples: 233,347
Min (total): 1 μs
Max (total): 2,584.584 μs
Avg (total): 11.062 μs

NODE_ENV=production node run.js brave 
* brave
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 27,980.061 μs
Avg deserialization time (100 samples): 30,396.855 μs
Serialized size: 3,508 KiB
List parsing time: 103,161.333 μs
Initialization time: 6,196.292 μs

Total requests: 233,347
Total match: 94,292
Total no match: 139,055

Number of samples: 94,292
Min match: 1.333 μs
Max match: 1,639.292 μs
Avg match: 7.774 μs

Number of samples: 139,055
Min no match: 1.416 μs
Max no match: 10,648.042 μs
Avg no match: 16.97 μs

Number of samples: 233,347
Min (total): 1.333 μs
Max (total): 10,648.042 μs
Avg (total): 13.254 μs

NODE_ENV=production node run.js adblockfast 
* adblockfast
Processed 10,000 requests
Processed 20,000 requests
Processed 30,000 requests
Processed 40,000 requests
Processed 50,000 requests
Processed 60,000 requests
Processed 70,000 requests
Processed 80,000 requests
Processed 90,000 requests
Processed 100,000 requests
Processed 110,000 requests
Processed 120,000 requests
Processed 130,000 requests
Processed 140,000 requests
Processed 150,000 requests
Processed 160,000 requests
Processed 170,000 requests
Processed 180,000 requests
Processed 190,000 requests
Processed 200,000 requests
Processed 210,000 requests
Processed 220,000 requests
Processed 230,000 requests
Processed 240,000 requests

Avg serialization time (100 samples): 339.485 μs
Avg deserialization time (100 samples): 330.318 μs
Serialized size: 127 KiB
List parsing time: 3,068.166 μs
Initialization time: 3,988.542 μs

Total requests: 233,347
Total match: 80,912
Total no match: 152,435

Number of samples: 80,912
Min match: 0.25 μs
Max match: 215.667 μs
Avg match: 2.028 μs

Number of samples: 152,435
Min no match: 0.958 μs
Max no match: 6,428,931.792 μs
Avg no match: 44.991 μs

Number of samples: 233,347
Min (total): 0.25 μs
Max (total): 6,428,931.792 μs
Avg (total): 30.094 μs

@seia-soto
Copy link
Member Author

Base: ghostery:master
Target: seia-soto:emit-cosmetic-filter-matches


Avg serialization time (100 samples): 190.044 μs (+ 59.886 μs)
Avg deserialization time (100 samples): 22.983 μs (- 42.825 μs)
Serialized size: 1,866 KiB
List parsing time: 115,573.042 μs (+ 14,799.876 μs)
Initialization time: 21,434.958 μs (+ 1,079.167 μs)

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.125 μs (eq)
Max match: 1,847.125 μs (+ 100.458 μs)
Avg match: 6.277 μs (+ 0.123 μs)

Number of samples: 139,053
Min no match: 1.25 μs
Max no match: 4,634.208 μs (+ 1,192.166 μs)
Avg no match: 8.468 μs (+ 0.104 μs)

Number of samples: 233,347
Min (total): 1.125 μs
Max (total): 4,634.208 μs (+ 1,192.166 μs)
Avg (total): 7.583 μs (+ 0.112 μs)

@seia-soto
Copy link
Member Author

Updated benchmarking.

Skipping: serialization, list parsing, and initialization time - as these are not affected by this PR

For matched filters (94k samples), the maximum matching time increased a lot: from 1,770.5 μs to 4,453.25 μs. This can be seen as a big deal but if we look at the average: from 6.62 μs to 6.906 μs - , it shows that the processing time grows by following the linear graph.

For exception + unmatched filters (139k samples), the maximum matching time decreased: from 5,513.208 μs to 3,402.334 μs. This is because this PR dropped maximum 3 comparisons of if statements for exceptions if there's no listeners.

For the overall result (94k+139k samples), see the following:

  • min: from 1.208 μs to 1.292 μs
  • max: from 5,513.208 μs to 4,453.25 μs
  • avg: from 7.846 μs to 8.183 μs
Full logs
(seia-soto:emit-cosmetic-filter-matches)

Avg serialization time (100 samples): 254.492 μs
Avg deserialization time (100 samples): 32.152 μs
Serialized size: 1,866 KiB
List parsing time: 147,284.666 μs
Initialization time: 21,659.791 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.292 μs
Max match: 4,453.25 μs
Avg match: 6.906 μs

Number of samples: 139,053
Min no match: 1.375 μs
Max no match: 3,402.334 μs
Avg no match: 9.048 μs

Number of samples: 233,347
Min (total): 1.292 μs
Max (total): 4,453.25 μs
Avg (total): 8.183 μs
(ghostery:master)

Avg serialization time (100 samples): 256.709 μs
Avg deserialization time (100 samples): 32.246 μs
Serialized size: 1,866 KiB
List parsing time: 151,396.167 μs
Initialization time: 23,166.625 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.208 μs
Max match: 1,770.5 μs
Avg match: 6.62 μs

Number of samples: 139,053
Min no match: 1.334 μs
Max no match: 5,513.208 μs
Avg no match: 8.678 μs

Number of samples: 233,347
Min (total): 1.208 μs
Max (total): 5,513.208 μs
Avg (total): 7.846 μs

Copy link
Member

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets try to figure out if we can fix the performance degradation

@seia-soto
Copy link
Member Author

After the optimisation, the performance overhead is in minimal considering the CPU time difference coming from list parsing time.

For the matching process: min -0.041 μs, max -12.501 μs, avg +0.016 μs
For the excepting process: min eq, max +71.833 μs, avg -0.111 μs
For the overall process: min -0.041 μs, max +71.833 μs, avg -0.06 μs

Full logs
(seia-soto:emit-cosmetic-filter-matches)

Avg serialization time (100 samples): 241.41 μs
Avg deserialization time (100 samples): 60.485 μs
Serialized size: 1,866 KiB
List parsing time: 96,548.417 μs
Initialization time: 22,948.458 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.167 μs
Max match: 1,794.542 μs
Avg match: 6.294 μs

Number of samples: 139,053
Min no match: 1.25 μs
Max no match: 3,339.25 μs
Avg no match: 8.436 μs

Number of samples: 233,347
Min (total): 1.167 μs
Max (total): 3,339.25 μs
Avg (total): 7.57 μs
(ghostery:master)

Avg serialization time (100 samples): 268.007 μs
Avg deserialization time (100 samples): 22.725 μs
Serialized size: 1,866 KiB
List parsing time: 96,420.709 μs
Initialization time: 19,974.833 μs

Total requests: 233,347
Total match: 94,294
Total no match: 139,053

Number of samples: 94,294
Min match: 1.208 μs
Max match: 1,780.041 μs
Avg match: 6.278 μs

Number of samples: 139,053
Min no match: 1.25 μs
Max no match: 3,267.417 μs
Avg no match: 8.547 μs

Number of samples: 233,347
Min (total): 1.208 μs
Max (total): 3,267.417 μs
Avg (total): 7.63 μs

packages/adblocker/src/events.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/bucket/cosmetic.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved

// Additional context given from user
matchType: FilterType.COSMETIC;
reference: any;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already commented on the naming of reference in another thread. Would it also make sense to type it with a generic type parameter T instead of any?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've discussed that and IMO a generic type would influence all signatures by putting a strong emphasis on itself, even if no listeners are in use.
What I mean, new users of for example getCosmeticsFilters, should not think about such T.

packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved
Comment on lines +922 to +937
url,
domain,
hostname,

classes,
hrefs,
ids,

allowGenericHides,
allowSpecificHides,

getBaseRules,
getInjectionRules,
getExtendedRules,
getRulesFromDOM,
getRulesFromHostname,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. Would it make sense to reuse part of the object we already create in the arguments for the function call above instead of duplicating?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like this?

const context: CosmeticFilterMatchingContext = {
   ...arguments[0],
   isFilterExcluded: undefined,
   filterType: FilterType.COSMETIC,
};

packages/adblocker/src/engine/engine.ts Outdated Show resolved Hide resolved

export type CosmeticFilterMatchingContext = CosmeticFilterMatchingContextBase &
Partial<
Omit<Parameters<FilterEngine['getCosmeticsFilters']>[0], 'callerContext'> &
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not needed

Comment on lines +788 to +790
if (htmlSelectors.length !== 0) {
this.emit('html-filtered', htmlSelectors, url, context);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be in the this.hasListeners('html-filtered') check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: New Feature 🚀 Increment minor version when merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve feedback from getCosmeticsFilters
3 participants