Repository navigation
Noticeably reduced performance with version 2 #244
Description
Activity
@dwightwatson thank you for reporting the issue!
We did run some performance checks on the new version, for example we took this transformation:
https://cloudinary.com/documentation/php1_image_manipulation#adding_text_and_image_overlaysAnd ran it 10000 times in a loop.
On my computer it took:
v1 : 2.422s
v2: 2.657sYou can see some performance decrease of around 10% for just generating the transformations.
Is that the difference you are experiencing?
If you could provide more details, maybe send a few typical transformations that you use, we could investigate it further.
I'm not entirely sure - I'm waiting on New Relic to get back up and running so I can crunch the numbers there, otherwise I'll see if I can replicate locally. I thought it was worth opening an issue just in case it was a more widespread problem. My use-case is literally just generating signed URLs so I'm surprised there would be any performance change.
We also face this issue. In some payloads we generate lots of image URLs (like several hundreds) and v2 seems to worsen performance considerably. We're also a bit confused why supposedly simple string transformation takes so much time...
@grubersjoe Just checking if you can share a code snippet so that we can test it on our end.
I ended up biting the bullet and moving to v2 regardless because of the deprecation warnings from v1. Also realised that using signed vs non-signed URLs was a performance drain (makes sense in hindsight but disappointing nonetheless).
Both v2 and v3 have issues with excessive configuration setup and a lack of caching in that. Every call requires setting up all the configs again and again.
I did some profiling with xdebug profiler. If you've never used it, it's very simple https://xdebug.org/docs/profiler. Just checkout this repo: https://github.com/joshua-bn/Cloudinary-PHP-SDK-Analysis and then run the docker commands to get the output. Run your cachegrind tool of choice and view the output.
(forgive the AI generated code. I had it do this while I was working on other things)
All the test does it output 100 images (50 urls and 50 image tags)
You see, for 100 images it is calling safeImplode() 16k times. safeFilterFunc() calls strlen() 19k times - that's 190 times per image.
I use Cloudinary to output somewhere around 60 images per page. It takes longer to generate simple strings than it does to get the 48 products I'm displaying on the page from ElasticSearch.
Hi @joshua-bn. Thanks for flagging this. I have raised a ticket internally for us to look into this in more detail (ref SNI-8453) and we will let you know the outcome
Reacted by Joshua DickersonHello, do you have any news on this issue ?
Unfortunately not. This is in our backlog, and when there is an update to share, someone from Cloudinary will update this ticket
I had a try on #425 🤞
Hi everyone — a quick update for anyone still subscribed to this issue.
We've just shipped a round of performance work that targets exactly the URL-generation hot path you flagged here. It builds on top of community contributions and analysis:
- PR feat: Slight performance improvements #425 by @kissifrot —
feat: Slight performance improvements(deep-clone fast path forConfigurationand a few smaller wins on the URL-build path). - The detailed v2 vs v3 profiling write-up by @joshua-bn (Cloudinary-PHP-SDK-Analysis), which made it very easy to see where time was actually going.
On top of those, we landed:
- A proper deep-clone for
Configuration(and full test coverage for it) soAsset/Tagconstruction stops re-parsing the URL config on every call. - Memoization of
StringUtils::camelCaseToSnakeCase/snakeCaseToCamelCaseandClassUtils::getConstantsin the transformation builder (these were called tens of thousands of times per page on URL-heavy workloads). - Tighter
ArrayUtilspaths (isAssoc→array_is_list,safeFilter/safeImplodeno longer allocate closures per call, etc.).
Releases
cloudinary/cloudinary_php3.1.3cloudinary/transformation-builder-sdk2.1.4 (pulled in automatically)
Numbers
Running @joshua-bn's exact 100-op workload (50 ×
Media::fromParams+ 50 ×ImageTag::fromParams, with realistic transformations) on PHP 8.x:per op per 100-op pass Before (3.1.2 + sdk 2.1.3) ~350 µs ~35 ms After (3.1.3 + sdk 2.1.4) ~118 µs ~12 ms Roughly 3× faster end-to-end on that workload, with peak memory unchanged (~4 MB). Internally,
Configuration::__constructcalls dropped from ~1,400 to 1 per workload, andsnakeCaseToCamelCasecalls from ~28,000 to ~1,400.If you give 3.1.3 a try and still see something slow on your side, please drop a comment with a small repro (a snippet of how you're calling the SDK in the hot path) — happy to keep iterating.
Thanks again to @kissifrot and @joshua-bn for the contributions and analysis that made this round possible.
- PR feat: Slight performance improvements #425 by @kissifrot —
Bug report for Cloudinary PHP SDK
Before proceeding, please update to latest version and test if the issue persists
Describe the bug in a sentence or two.
After upgrading to the new PHP SDK (from 1.x to 2.x) I noticed our 50th percentile drop considerably. I isolated the change and reverted back to 1.x and saw my response times go back to where they were previously. Unfortunately New Relic wasn't running correctly so I didn't manage to capture any better metrics.
I've opened this issue to see if anyone else has noticed similar issues. I would not have expected simply upgrading Cloudinary to have an a noticeable impact on response time. Additionally - we only use the PHP SDK for URL generation, not for uploading assets or anything, so it should be pretty negligible.
Issue Type (Can be multiple)
Operating System
Environment and Frameworks (fill in the version numbers)