Skip to content

perf: avoid array allocations in OTP hot path#283

Open
pataar wants to merge 1 commit into
Spomky-Labs:11.6.xfrom
pataar:perf/get-parameter-direct-access
Open

perf: avoid array allocations in OTP hot path#283
pataar wants to merge 1 commit into
Spomky-Labs:11.6.xfrom
pataar:perf/get-parameter-direct-access

Conversation

@pataar

@pataar pataar commented Jun 10, 2026

Copy link
Copy Markdown

Summary

Two micro-optimizations on the generateOTP() hot path. No behavior change.

  • getParameter() reads $this->parameters directly instead of through getParameters(), which copies the array and conditionally appends issuer on every call. Hit 3+ times per generation (for algorithm, secret, digits).
  • generateOTP() hoists getDigits() to a local so the modulo and str_pad width no longer recompute it.

Combined savings multiply under TOTP::verify(..., leeway) (3 generations) and HOTP::verify(..., window) (up to N).

Why it's safe

getParameters() adds issuer dynamically, but getParameter('issuer') already threw — hasParameter('issuer') returns false because issuer lives in $this->issuer, never in $this->parameters. Same for label. Grep confirms no callers pass 'issuer'/'label' to getParameter. RFC 4226 / 6238 vector tests cover the full generation pipeline across SHA1/256/512.

Verified locally: PHPUnit (160 tests, 440 assertions), PHPStan, ECS, Rector, parallel-lint — all clean.

- getParameter() reads $this->parameters directly instead of going through
  getParameters(), which builds a new array (and conditionally appends the
  issuer) on every call. getParameter is called multiple times per
  generateOTP() via getDigest/getSecret/getDigits, so each generation paid
  several unnecessary allocations.
- generateOTP() hoists getDigits() to a local so str_pad and the modulo
  no longer recompute it.

Behavior is unchanged: callers reading 'issuer' via getParameter() already
threw (hasParameter('issuer') is false because issuer lives in $this->issuer),
and no internal callsite passes 'issuer' or 'label' to getParameter.
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

Successfully merging this pull request may close these issues.

1 participant