Skip to content
This repository has been archived by the owner on Feb 7, 2023. It is now read-only.

Improving Firefox performance: heap+asm pooling #154

Open
twiss opened this issue Jun 29, 2018 · 0 comments · May be fixed by #155
Open

Improving Firefox performance: heap+asm pooling #154

twiss opened this issue Jun 29, 2018 · 0 comments · May be fixed by #155

Comments

@twiss
Copy link
Contributor

twiss commented Jun 29, 2018

In Firefox, repeatedly constructing AES objects is really slow. Repeatedly allocating and discarding the heap and asm functions puts a lot of pressure on the Garbage Collector, and according to Firefox's profiler, it spends all of its time during encrypting/decrypting in the GC. That's not good.

In the old (JS) codebase, the static convenience functions used a shared heap and asm instance, which partially fixed this issue. However, if you needed the streaming API, and don't reuse the objects, you'd run into this issue. In the new (TS) codebase, this is presumably even worse, since the convenience functions allocate a new object every time, without reusing the heap+asm.

For @openpgpjs, instead of having a single shared heap, I've implemented a proof of concept of pooling the heap and asm functions: twiss@aa21f46. This improves performance by about 4x in Firefox for us.

However, it has to make some assumptions: because JS doesn't have destructors, it assumes that after you call finish(), you won't want to use the same object again for another encryption/decryption. If you do, you incur a small performance hit due to the extra AES_Reset. Of course, there are various obvious optimizations to be made here (e.g. don't AES_Reset if the key&iv stayed the same) which could even help if you repeatedly call the static functions with the same key, for example.

However, there are always pathological cases where it's better to manually manage AES objects, rather than pool heap+asm, for example if you instantiate a first AES object, use it, then instantiate a second AES object with a different key, and then use the first one again. For that case, we could either add a config option not to pool, or add a parameter to finish() indicating that you want to use the object again.

The implementation linked above is still on the JS codebase, but would you be interested in a PR for pooling for the TS codebase?

@twiss twiss linked a pull request Jul 30, 2018 that will close this issue
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant