From 9173e457bed6af0d058e9f338af31a716a415f83 Mon Sep 17 00:00:00 2001 From: Alexey Spiridonov Date: Wed, 30 Oct 2024 03:53:43 -0700 Subject: [PATCH] `if constexpr` shortcut for `CancellationToken::merge(x)` Summary: This takes the `merge1` microbench (stacked) from 74ns to 24ns without regressing anything. This is helpful for generic programs, where the pack MIGHT have 1 element, and there's no reason to shortcut this on the client side. Reviewed By: Orvid Differential Revision: D65044520 fbshipit-source-id: e2f91bbc69439d5759d79d8a5391f5ba3e0239ed --- folly/CancellationToken-inl.h | 17 +++++++++++------ folly/test/CancellationTokenTest.cpp | 6 ++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/folly/CancellationToken-inl.h b/folly/CancellationToken-inl.h index 9d4ffad7d66..f28720b7f91 100644 --- a/folly/CancellationToken-inl.h +++ b/folly/CancellationToken-inl.h @@ -448,12 +448,17 @@ std::pair*> CancellationSource::create( template inline CancellationToken CancellationToken::merge(Ts&&... tokens) { - bool canBeCancelled = detail::variadicDisjunction(tokens.canBeCancelled()...); - return canBeCancelled - ? CancellationToken( - detail::FixedMergingCancellationState::create( - std::forward(tokens)...)) - : CancellationToken(); + if constexpr (sizeof...(Ts) == 1) { + return (tokens, ...); + } else { + bool canBeCancelled = + detail::variadicDisjunction(tokens.canBeCancelled()...); + return canBeCancelled + ? CancellationToken( + detail::FixedMergingCancellationState::create( + std::forward(tokens)...)) + : CancellationToken(); + } } } // namespace folly diff --git a/folly/test/CancellationTokenTest.cpp b/folly/test/CancellationTokenTest.cpp index 8a058c9c1ca..e76394b23b4 100644 --- a/folly/test/CancellationTokenTest.cpp +++ b/folly/test/CancellationTokenTest.cpp @@ -293,6 +293,12 @@ TEST(CancellationTokenTest, MergedToken) { EXPECT_FALSE(token.canBeCancelled()); } +TEST(CancellationTokenTest, Merging1TokenIsEfficient) { + CancellationSource src; + CancellationToken tok = src.getToken(); + EXPECT_TRUE(tok == CancellationToken::merge(tok)); +} + TEST(CancellationTokenTest, TokenWithData) { struct Guard { int& counter;