imagehash icon indicating copy to clipboard operation
imagehash copied to clipboard

Adapter for GD / no image intervention (performance improvement)

Open garygreen opened this issue 4 years ago • 11 comments

Is there any interest in having a faster adapter which just uses PHP GD to process images rather than going through Intervention package? On my machine using simple gd operations such as imagecolorsforindex and imagecolorat to get colours is around double the speed as using Intervention (I assume because that has a lot of overhead under the hood for validating arguments, creating lots of objects, garbage collection, etc)

As a side note - maybe the intervention package could be an optional inclusion (if you want to support Imagemagick) but by default this library could focus on gd support only out the box? Pulling in intervention for some basic image calculations probably isn't necessary.

garygreen avatar Jan 27 '20 21:01 garygreen

Intervention does add a lot of flexibility for different library support.

Since different algorithm implementations have different sizing and colorization needs it's really handy to have something like Intervention available. I do wonder where this performance hit comes from through.

jenssegers avatar Jan 28 '20 08:01 jenssegers

Since different algorithm implementations have different sizing and colorization needs it's really handy to have something like Intervention available

As far as I can see from the different implementations only really do two things;

  1. Resize
  2. Pick colors

That's basically all that's needed and you can do that with real basic php GD functions.

Just as comparison, I implemented a DifferenceHash using gd and this is the difference in speed:

With gd only implementation gd

With current Intervention implementation (still uses GD under the hood) intervention

In summary, gd takes 6 seconds and intervention takes 25 seconds.

I haven't digged any further into why it's much quicker - but I suspect intervention is doing a lot of operations when opening images, creating lots of objects, garbage collection etc. When your processing hundreds and thousands of image this makes a huge difference in speed.

garygreen avatar Feb 01 '20 16:02 garygreen

garygreen, could you please share gd version of DifferenceHash?

scratcher28 avatar May 28 '20 06:05 scratcher28

@scratcher28 sure, he it is: https://gist.github.com/garygreen/dbb565fa1efbf5b8179d4570e88adb25

Take note - currently this package requires Imagick due to the interface, so in itself the above code won't be "plug and play" - will likely need to fork the package and adjust the interface to remove that typehint.

Disclaimer: I haven't thouroughly tested it, so you may want to double check its coming back with the same values as the current implementation.

garygreen avatar May 28 '20 13:05 garygreen

I wonder why Intervention is so much slower than the native implementation. Would be nice to get some Blackfire profiling on this!

jenssegers avatar May 28 '20 16:05 jenssegers

Ok so I've done some further digging. It turns out my custom implementation was using a different way of resizing the image as compared to Intervention which was the cause of the big difference in speed.

Intervention uses imagecopyresampled which as far as I'm aware uses a higher quality resizing algorithm at a much higher cost of CPU. My original code was using imagecopyresized.

You can see the various speed and memory differences in summary here:

diff

Notes:

  • "gd only" meaning its my custom implementation and isn't using Intervention.
  • The 2nd and 3rd row both generate the same hash, 1st row generates a diff hash due to lower quality resize

Without using Intervention and using the same resize algorithm it's still faster and reduces memory usage:

speed diff - same algorithm

memory diff - same algorithm


So I guess the real question is do you really need to use a higher quality resize algorithm when generating a difference hashes? My first intinct is no, as to a computer it should still be able to compute that two slightly lower quality images are alike - the difference in higher quality resize is mostly valuable to human eyes?

garygreen avatar May 28 '20 22:05 garygreen

Interesting. I also don't really see a way to influence what kind of resizing method Intervention uses internally.

jenssegers avatar May 29 '20 07:05 jenssegers

I could look into abstracting away Intervention so that you can swap out the image manipulation logic with something else.

jenssegers avatar May 29 '20 07:05 jenssegers

Yeah that would be good. Honestly I would just copy the few lines of code that Intervention is using to resize the images and then ditch Intervention package, just straight up use GD. Then do a major version bump. There's really little use in using Intervention in a package like this, it's way overkill.

Also another thing - Intervention is presevering transpanrecy and other stuff for PNG images - that bumps up the time and isn't needed for this package.

As for the quality resize, probably needs more testing to see if it does have any impact on comparing difference hashes - I would assume it doesn't, as ultimately it resizes the image to 8x8 and then computes the hash. Quality isn't really that important it's more about comparing light differences.

garygreen avatar May 29 '20 13:05 garygreen

Doing that would not allow people with Imagick to use this package though. My mean reason to use Intervention was to support both Imagick and GD.

jenssegers avatar May 29 '20 13:05 jenssegers

As you say, Intervention can still be used as an optional thing though. So if you do have Imagick installed on your server you can install Intervention and use that as the driver. Most people I think would be happy with straight up GD though - doesn't require any additional configuration on server. 🤷‍♀️

I think most of the value in this package comes from the algorithm itself, not nesscarily what programs it uses to resize + scale the images. As long as it computes hashes that are useful and good at comparisons.

garygreen avatar May 29 '20 14:05 garygreen