/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include enum class V {}; enum class E {}; FOLLY_ALWAYS_INLINE E check_folly_expected_coro_await_unexpected_i(E i) { using X = folly::Expected; auto fun = [i]() -> X { co_await folly::makeUnexpected(i); folly::compiler_may_unsafely_assume_unreachable(); }; return fun().error(); } FOLLY_ALWAYS_INLINE E check_folly_expected_coro_await_expected_error_i(E i) { using X = folly::Expected; auto fun = [i]() -> X { co_await X{folly::makeUnexpected(i)}; folly::compiler_may_unsafely_assume_unreachable(); }; return fun().error(); } FOLLY_ALWAYS_INLINE E check_folly_expected_coro_return_unexpected_i(E i) { using X = folly::Expected; auto fun = [i]() -> X { // co_return folly::makeUnexpected(i); }; return fun().error(); } FOLLY_ALWAYS_INLINE E check_folly_expected_coro_return_expected_error_i(E i) { using X = folly::Expected; auto fun = [i]() -> X { // co_return X{folly::makeUnexpected(i)}; }; return fun().error(); } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_await_unexpected(E i) { return check_folly_expected_coro_await_unexpected_i(i); } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_await_expected_error(E i) { return check_folly_expected_coro_await_expected_error_i(i); } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_return_unexpected(E i) { return check_folly_expected_coro_return_unexpected_i(i); } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_return_expected_error(E i) { return check_folly_expected_coro_return_expected_error_i(i); } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_await_unexpected_eptr( // folly::exception_wrapper eptr) { using X = folly::Expected; auto fun = [&]() -> X { co_await folly::makeUnexpected(std::move(eptr)); folly::compiler_may_unsafely_assume_unreachable(); }; auto e = fun().error().get_exception(); return e ? *e : E{}; } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_await_expected_error_eptr( folly::exception_wrapper eptr) { using X = folly::Expected; auto fun = [&]() -> X { co_await X{folly::makeUnexpected(std::move(eptr))}; folly::compiler_may_unsafely_assume_unreachable(); }; auto e = fun().error().get_exception(); return e ? *e : E{}; } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_return_unexpected_eptr( folly::exception_wrapper eptr) { using X = folly::Expected; auto fun = [&]() -> X { // co_return folly::makeUnexpected(std::move(eptr)); }; auto e = fun().error().get_exception(); return e ? *e : E{}; } extern "C" FOLLY_KEEP FOLLY_NOINLINE E check_folly_expected_coro_return_expected_error_eptr( folly::exception_wrapper eptr) { using X = folly::Expected; auto fun = [&]() -> X { // co_return X{folly::makeUnexpected(std::move(eptr))}; }; auto e = fun().error().get_exception(); return e ? *e : E{}; } BENCHMARK(noop_i_0x100, iters) { while (iters--) { for (size_t i = 0; i < 0x100; ++i) { auto res = E(7); folly::compiler_must_not_elide(res); } } } BENCHMARK(await_unexpected_i_0x100, iters) { while (iters--) { for (size_t i = 0; i < 0x100; ++i) { auto res = check_folly_expected_coro_await_unexpected_i(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(await_expected_error_i_0x100, iters) { while (iters--) { for (size_t i = 0; i < 0x100; ++i) { auto res = check_folly_expected_coro_await_expected_error_i(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(return_unexpected_i_0x100, iters) { while (iters--) { for (size_t i = 0; i < 0x100; ++i) { auto res = check_folly_expected_coro_return_unexpected_i(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(return_expected_error_i_0x100, iters) { while (iters--) { for (size_t i = 0; i < 0x100; ++i) { auto res = check_folly_expected_coro_return_expected_error_i(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(noop_0x10, iters) { while (iters--) { for (size_t i = 0; i < 0x10; ++i) { auto res = std::invoke([]() FOLLY_NOINLINE { return E(7); }); folly::compiler_must_not_elide(res); } } } BENCHMARK(await_unexpected_0x10, iters) { while (iters--) { for (size_t i = 0; i < 0x10; ++i) { auto res = check_folly_expected_coro_await_unexpected(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(await_expected_error_0x10, iters) { while (iters--) { for (size_t i = 0; i < 0x10; ++i) { auto res = check_folly_expected_coro_await_expected_error(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(return_unexpected_0x10, iters) { while (iters--) { for (size_t i = 0; i < 0x10; ++i) { auto res = check_folly_expected_coro_return_unexpected(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(return_expected_error_0x10, iters) { while (iters--) { for (size_t i = 0; i < 0x10; ++i) { auto res = check_folly_expected_coro_return_expected_error(E(7)); folly::compiler_must_not_elide(res); } } } BENCHMARK(await_unexpected_eptr, iters) { auto eptr = folly::make_exception_wrapper(7); while (iters--) { auto res = check_folly_expected_coro_await_unexpected_eptr(eptr); folly::compiler_must_not_elide(res); } } BENCHMARK(await_expected_error_eptr, iters) { auto eptr = folly::make_exception_wrapper(7); while (iters--) { auto res = check_folly_expected_coro_await_expected_error_eptr(eptr); folly::compiler_must_not_elide(res); } } BENCHMARK(return_unexpected_eptr, iters) { auto eptr = folly::make_exception_wrapper(7); while (iters--) { auto res = check_folly_expected_coro_return_unexpected_eptr(eptr); folly::compiler_must_not_elide(res); } } BENCHMARK(return_expected_error_eptr, iters) { auto eptr = folly::make_exception_wrapper(7); while (iters--) { auto res = check_folly_expected_coro_return_expected_error_eptr(eptr); folly::compiler_must_not_elide(res); } } int main(int argc, char** argv) { folly::Init init(&argc, &argv); folly::runBenchmarks(); return 0; }