rust - futures::executor::block_on 和 block_in_place 之间是否存在性能差异

标签 rust rust-tokio

我在同步方法内调用了异步代码(此方法是特征的一部分,我无法异步实现它),因此我使用 block_on 来等待异步调用完成。

同步方法将从异步代码中调用。

因此,应用程序位于 #[tokio::main] 中,当发生某些事件(端点命中)时,它会调用同步方法,同步方法将调用一些异步代码并等待它完成并返回。

事实证明 block_on 不能在异步代码中使用。我发现 tokio::task::block_in_place 会在异步上下文中生成同步上下文,从而允许在其中调用 block_on 。

所以该方法现在看起来像这样:

impl SomeTrait for MyStruct {
    fn some_sync_method(&self, handle: tokio::runtime::Handle) -> u32 {
        tokio::task::block_in_place(|| {
            handle.block_on(some_async_function())
        }
    }
}

此实现更好还是使用 futures::executor::block_on 代替:

impl SomeTrait for MyStruct {
    fn some_sync_method(&self, handle: tokio::runtime::Handle) -> u32 {
        futures::executor::block_on(some_async_function())
    }
}

这两种实现之间的根本区别是什么?在什么情况下它们各自会更有效。

顺便说一句,这个方法被多次调用。这是网络服务器的一部分。

最佳答案

不要使用futures::executors::block_on()。即使在比较性能之前,还有一些更重要的事情需要考虑:futures::executors::block_on() 在这里是错误的,因为它会阻塞异步运行时。

As explained in block_in_place() docs :

In general, issuing a blocking call or performing a lot of compute in a future without yielding is problematic, as it may prevent the executor from driving other tasks forward. Calling this function informs the executor that the currently executing task is about to block the thread, so the executor is able to hand off any other tasks it has to a new worker thread before that happens. See the CPU-bound tasks and blocking code section for more information.

futures::executors::block_on() 可能会性能更高一些(虽然我没有进行基准测试),因为它不会通知执行程序。但这就是重点:您需要通知执行人。否则,您的代码可能会陷入困境,直到您的阻塞函数完成为止,基本上是串行执行的,而不利用设备的资源。

如果此代码是大部分代码,您可以重新考虑使用异步运行时。如果您只生成线程,可能会更有效。或者干脆放弃使用该库并仅使用异步代码。

关于rust - futures::executor::block_on 和 block_in_place 之间是否存在性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73269315/

相关文章:

reference - 是什么导致了这个 "cannot borrow as mutable"异常?

rust - 无法使用git存储库中的alacritty依赖关系

rust - 并发执行任务时无法将filter_map与buffer_unordered一起使用?

rust - 如何使用reqwest执行并行异步HTTP GET请求?

generics - 受另一个参数限制的通用参数

rust - 使 String 类型与 ARM 兼容?

rust - 引入魔术线后第二个可变借用错误消失

rust - 在Rust中使用 `tokio-ruSTLs`从TlsStream <TcpStream>读取

rust - 是否可以使用 Tokio 和 Juniper 在 GraphQL 对象字段中执行任何类型的并行计算?

types - 在 Rust 的 32 位机器中,f64 类型是如何表示的?