"sync-to-async" function/decorator 中本机异步函数和包装同步函数之间的区别?
Difference between native async functions and wrapping sync functions in a "sync-to-async" function/decorator?
作为我的问题的示例,我正在构建一个使用 web3.py 库的应用程序。这个库只能同步工作,但我要求我的应用程序是异步的。
web3.py 开发人员实际上正在努力将异步功能构建到库中,但这需要一些时间。与此同时,我所做的是使用 asyncer.asyncify() 包装我需要的任何 web3.py 同步函数,使它们在我的应用程序中异步工作,因此,我相信,我有 web3.py 完全异步工作。
这让我开始思考 - 库的作者编写本机异步函数与仅将所有现有同步函数包装在 Asyncer 之类的东西中有什么区别?会有任何性能差异吗?
换句话说,当他们可以使用像 Asyncer 这样的包装器 function/decorator 并将他们的整个库转换为异步时,他们为什么要花这么多时间将他们的库的同步实现转换为异步大概 1 天的工作就能实现?
我想说理想的异步代码应该只对 IO-bound 任务使用异步方式。在这种情况下,一切都会正常 in one thread.
在您提供的asyncer
的例子中,使用了线程池的方式执行under the hood。这对启动、切换线程和传递参数(使用队列)施加了一定的成本。
作为临时或折衷的解决方案,这可能是合适的。但是如果我们想为 IO-bound 解决方案获得更多性能,最好使用异步工具。
作为我的问题的示例,我正在构建一个使用 web3.py 库的应用程序。这个库只能同步工作,但我要求我的应用程序是异步的。
web3.py 开发人员实际上正在努力将异步功能构建到库中,但这需要一些时间。与此同时,我所做的是使用 asyncer.asyncify() 包装我需要的任何 web3.py 同步函数,使它们在我的应用程序中异步工作,因此,我相信,我有 web3.py 完全异步工作。
这让我开始思考 - 库的作者编写本机异步函数与仅将所有现有同步函数包装在 Asyncer 之类的东西中有什么区别?会有任何性能差异吗?
换句话说,当他们可以使用像 Asyncer 这样的包装器 function/decorator 并将他们的整个库转换为异步时,他们为什么要花这么多时间将他们的库的同步实现转换为异步大概 1 天的工作就能实现?
我想说理想的异步代码应该只对 IO-bound 任务使用异步方式。在这种情况下,一切都会正常 in one thread.
在您提供的asyncer
的例子中,使用了线程池的方式执行under the hood。这对启动、切换线程和传递参数(使用队列)施加了一定的成本。
作为临时或折衷的解决方案,这可能是合适的。但是如果我们想为 IO-bound 解决方案获得更多性能,最好使用异步工具。