evanw / thumbhash

A very compact representation of an image placeholder

Home Page:https://evanw.github.io/thumbhash/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Performance/speed comparison with BlurHash

ToshY opened this issue · comments

commented

The documentation/demo states the following:

Much faster to encode and decode

Howmuch faster compared to BlurHash? If you've done tests to compare performance/speed between ThumbHash and BlurHash, it would be nice to show these results.

I should probably remove that part of the website. I don't want that to be the focus of this. Partially because the performance doesn't matter too much (encode typically happens once and is stored, and decode is pretty trivial), partially because optimal performance isn't even a goal (it'd be pretty trivial to speed this up even more with SIMD or a hand-rolled cos implementation, but that goes against the goal of having simple code), and partially because BlurHash is slow for uninteresting reasons.

Some data points to answer your question, since I should still back it up (1 μs is a microsecond, which is 0.000001 seconds):

  • Encode:

    Language BlurHash encode ThumbHash encode ThumbHash speedup
    JavaScript 6,142 μs 622 μs 9.9x faster
    Swift (debug) 43,180 μs 1,502 μs 28.8x faster
    Swift (release) 1,859 μs 299 μs 6.2x faster
  • Decode:

    Language BlurHash decode ThumbHash decode ThumbHash speedup
    JavaScript 185 μs 166 μs 1.1x faster
    Swift (debug) 3,395 μs 405 μs 8.4x faster
    Swift (release) 79 μs 63 μs 1.2x faster

One big reason BlurHash is currently slower is that their sRGBToLinear function should really be implemented as a lookup table but isn't. That's a 2x speedup to BlurHash right there. I'm sure there are other easy wins too. I wouldn't be surprised if it's possible to make a BlurHash implementation that's just as fast as (or even faster than) ThumbHash since they are doing pretty similar things.

Another reason BlurHash's Swift implementation is so slow in debug builds is that they are using for-in loops instead of while loops (see e.g. woltapp/blurhash#215). This is a really dumb performance issue with the current Swift compiler implementation. You could argue that debug performance doesn't matter and that readability should be prioritized as long as release performance is good, so maybe BlurHash shouldn't even be changed. Personally I value quick iteration cycles with debug builds so I have tuned ThumbHash's code for that.