Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapter for GD / no image intervention (performance improvement) #50

Open
garygreen opened this issue Jan 27, 2020 · 11 comments
Open

Adapter for GD / no image intervention (performance improvement) #50

garygreen opened this issue Jan 27, 2020 · 11 comments

Comments

@garygreen
Copy link

garygreen commented Jan 27, 2020

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.

@jenssegers
Copy link
Owner

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.

@garygreen
Copy link
Author

garygreen commented Feb 1, 2020

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.

@scratcher28
Copy link

garygreen, could you please share gd version of DifferenceHash?

@garygreen
Copy link
Author

@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.

@jenssegers
Copy link
Owner

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

@garygreen
Copy link
Author

garygreen commented May 28, 2020

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?

@jenssegers
Copy link
Owner

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

@jenssegers
Copy link
Owner

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

@garygreen
Copy link
Author

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.

@jenssegers
Copy link
Owner

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.

@garygreen
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants