Avoid synchronization by cloning a prototype Mac
and reallocating buffers
#42
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've been thinking back on the conversation in #34, and I think I've found a best-of-both-worlds approach. To recap, the suggestion in #34 was to allocate a new buffer and instantiate a new
Mac
on each call togenerateOneTimePassword
to avoid synchronization, leading to higher throughput. The problem was that instantiating a newMac
was pretty slow.It turns out that cloning a
Mac
is actually pretty fast, though! We can't guarantee that cloning aMac
will be possible in all setups—some provider might have a non-cloneableHmacSHA512
implementation, for example—but it'll probably be true in most setups. This lets us makegenerateOneTimePassword
non-synchronized while still retaining thread safety, which seems like a win.This may come at the cost of a modest throughput decrease in the single-threaded case, but if it does, it's on the order of 1%, and I'd say that's a worthwhile price to pay.