google / webcrypto.dart

Cross-platform implementation of Web Cryptography APIs
https://pub.dev/packages/webcrypto
Apache License 2.0
78 stars 44 forks source link

Move all computation off-the-mainthread #6

Open jonasfj opened 3 years ago

jonasfj commented 3 years ago

This already the case on the web, or at-least it's moved the browser which is most likely moving it off-the-mainthread.

We should do the same on Android and iOS.

A workaround is to wrap functions using crypto with compute.

NOTE, the API is already fully async, so we should be able to move computation off the main thread, without breaking existing users of this package.

ThomasKliszowski commented 3 years ago

Hi @jonasfj,

I did exactly what you said in my project: wrapping webcrypto calls in compute. Note that compute seems really slow compared to the main thread execution. After investigation, it seems that the execution time is the same, but the Isolate spawning overhead is the main issue. I fixed that by reusing my Isolate. I even did better using a pool of Isolates with a LoadBalancer from https://pub.dev/packages/isolate.

Juste in case you decide to work on this, keep this in mind 👍 .

Hope that helps, have a good day!

jonasfj commented 3 years ago

I suspect the hard part with an isolate pool is to manage it's life-cycle without being forced to extend the public API for the package with methods to define this life-cycle.

ThomasKliszowski commented 3 years ago

Indeed, I can't disagree, it was way easier for me to do it directly in my project. But the compute method add so much overhead that I couldn't use it. Maybe just do nothing in your lib and let people wrap their code in an Isolate if they want to? Some documentation could be enough.

olavemil commented 2 years ago

Note that while the debug overhead of isolate spawning is huge, in my experience a release build will perform much better. Because the debug performance is so horrible (especially in emulators), I have ended up with a wrapper something like this, that performs rather well in all scenarios:

Future<R> doWork<T, R>(void Function(T input) work, T input) {
  if (kDebugMode && (Platform.isAndroid || Platform.isIOS)) {
    return work(input);
  }
  return compute(work, input);
}