Open FallingSnow opened 7 years ago
Can you provide an example to reproduce slow performance? Note that chromium-dev itself is unstable, so you have to test on the latest stable build to get more meaningful result.
Got a test case done. If you use chromium, you will need to add --allow-file-access-from-files
to your command line arguments.
libflif-performance-test-case.zip
In script.js you will see
decodeWebWorker(buffer);
// decodeSync(buffer);
Just switch between commenting each other and reload the page to see the difference.
I ran some numbers. Both were set to scale to the image's native resolution of 5146x2935.
Web worker decode took 17053.045000000002 milliseconds.
Sync decode took 11826.785 milliseconds.
Web worker decode took 5226.260000000002 milliseconds longer.
When using poly-flif's scaling the results are much more dramatic.
Using google-chrome-stable, same image, native resolution.
Web worker decode took 16493.545 milliseconds.
Sync decode took 12338.705000000002 milliseconds.
Web worker decode took 4154.8399999999965 milliseconds longer.
Currently one key part is memory-growth compiler option. poly-flif currently gives -s TOTAL_MEMORY=100000000
, which forces 100 MiB memory allocation from the start. On the other hand, libflif.js currently gives -s ALLOW_MEMORY_GROWTH=1
, which allows starting with small memory space and growing if needed. However, the memory growth option limits compiler optimization which can cause slower speed.
WebAssembly will allow chasing two rabbits but the current asm.js can only chase one, smaller memory space or faster performance.
The scaling decoder option is yet implemented, but you can still use it by manually inserting decoder.setScale(scaleX, scaleY)
decoder.setScale(scale)
on the worker script if you want. I just opened #8 for this.
Thanks for the responses. I'm not sure yet, but I think the scaling option will add enough of a performance boost for the time being. If you don't mind, I might ask you for advice in the future about memory growth. I was able to deduce that I can use decoder.setResize
and decoder.setFit
so that's awesome.
Is there a way I can have the web worker just decode once (the highest possible quality) rather than in waves? (In my experience each wave takes just as long as a single max quality decode)
BTW, correct syntax is decoder.setScale(scale)
for anyone reading this in the future.
You can decoder.setFirstCallbackQuality(10000)
to get only single wave.
Thank you.
BTW,
(In my experience each wave takes just as long as a single max quality decode)
I can reproduce this and I doubt this is a problem on my code. The callback does not cause much delay so this is possibly a FLIF decoder problem.
Well, I solved this issue by doing a decode where setFit was set to a much smaller size, this gives a quick decode and image to display. Then follow up with the correct setFit.
Basically the same thing you were trying to accomplish without the delay.
Then follow up with the correct setFit.
You mean you call decodeWebWorker()
multiple time with different setFit
values?
Yes.
Right now I'm trying to get the right setFit value for the final decode without knowing the image's dimensions beforehand. I basically want the opposite of --resize=WxH
so that its lossy downscaled image to at least WxH
instead of lossy downscaled image to fit inside WxH
.
Sadly I'm still trying to figure out if this is possible without knowing the image's dimensions beforehand.
libflif is much slower than poly-flif in my test and more unstable. Do you know if there are any specific optimizations that poly-flif does versus libflif?
https://github.com/UprootLabs/poly-flif/issues/27