Opened 4 weeks ago
Last modified 28 hours ago
#63026 new defect (bug)
Improve performance of bcrypt related unit tests
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 6.8 | Priority: | normal |
Severity: | normal | Version: | trunk |
Component: | Security | Keywords: | needs-patch |
Focuses: | tests | Cc: |
Description
It seems that when using PHP 8.4, there is a considerable decrease in overall performance in combination with MySQL databases.
This was spotted because there have been more frequent occurrences of the PHPUnit test suite failing due to the configured 20 minute timeout being exceeded. For an example, see the annotations at the bottom of this run summary. The related jobs take 2-3x longer to complete.
The Performance Testing workflow runs using the latest
tag for PHP, which currently is applied to the 8.2 container where this decrease is not apparent.
Change History (14)
This ticket was mentioned in PR #8416 on WordPress/wordpress-develop by @desrosj.
4 weeks ago
#3
- Keywords has-patch added
The PHPUnit test suite when run on PHP 8.4 with MySQL 8.4 seems to be taking 2-3x the amount of time as all other jobs. This switches the performance testing workflow to use PHP 8.4 to see if there is a noticeable change in measured performance.
Trac ticket: https://core.trac.wordpress.org/ticket/63026
#4
@
4 weeks ago
Perhaps the new password hashing (#21022) might be a factor here? It seems that password_hash()
with BCrypt is (intentionally) slower in PHP 8.4 than in earlier versions.
#5
@
4 weeks ago
- Keywords has-patch removed
Ok the culprit is indeed the commit that introduced the switch to bcrypt. The run time for the PHP 8.4 unit test jobs on GitHub Actions jumped from around 7-8 minutes to around 14-15.
Some notes:
- The unit tests for all PHP versions, not just 8.4, have slowed. The impact on 8.4 is the greatest, presumably due to the higher bcrypt cost.
- Prior to the commit I had run several rounds of before and after performance tests of the test suite locally, however I was only doing this with the
--group auth
filter. The difference is less noticeable when only testing a subset, and there was an expected increase in the test time anyway due to an increase in the number of tests and the fact they make heavy use of the password hashing and checking functions. - The root cause is likely due to the high number of tests that make use of user fixtures. Each time a user fixture is created, a hash of their password is generated, which was previously handled by phpass but is now handled buy bcrypt which, by design, is slower.
- Ideally any tests that need a user fixture but don't care about the user's password would bypass the password hashing, but that will require adjustments to tests relating to authentication.
#6
@
4 weeks ago
There are a over 1,240 calls to create a user via the user factory when the tests run (single site standard test suite). Each of these calls causes a password hash to be generated.
This ticket was mentioned in Slack in #core-performance by johnbillion. View the logs.
2 weeks ago
#8
@
2 weeks ago
- Focuses performance removed
Removing the performance focus as this is confined to the tests and the performance tests are not otherwise indicating a regression.
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
9 days ago
#10
@
9 days ago
- Focuses tests added
As per today's bug scrub: adding tests
focus and keeping it in the milestone for now.
#11
@
7 days ago
- Component changed from Database to Security
- Keywords needs-patch added; needs-testing removed
- Summary changed from Investigate potential performance regressions when using PHP 8.4 to Improve performance of bcrypt related unit tests
Updating the title to reflect that this is more pronounced in but not specific to 8.4.
Some additional context. There was a brief conversation in Slack around this where build tool specific issues were mostly ruled out.
I've also gone and created a PR that runs the performance tests using PHP 8.4, and it seems to confirm that there is a 1-5% decrease in nearly all metrics across the board. I also tried using MySQL 9.2 and the results were more mixed (he majority of metrics declined, though not by as much).
For the short term, I am going to change the timeout value for the PHPUnit workflows when 8.4 is being tested to prevent cancellations. The conservative timeout value did it's job here and helped us find a performance problem! 🙌
I'm also going to milestone this for 6.8 for investigation purposes. If there's nothing actionable prior to RC1, we can punt and continue exploring for 6.9.