2

I'm wondering if there are any noticeable differences in performance between foo and bar:

class Interface:
    def __init__(self, loop):
        self.loop = loop

    def foo(self, a, b):
        return self.loop.run_until_complete(self.bar(a, b))

    async def bar(self, a, b):
        v1 = await do_async_thing1(a)
        for i in range(whatever):
            do_some_syncronous_work(i)
        v2 = await do_async_thing2(b, v1)
        return v2

async def call_foo_bar(loop):
    a = 'squid'
    b = 'ink'
    interface = Interface(loop)
    v_foo = interface.foo(a, b)
    v_bar = await interface.bar(a, b)

But will the use of run_until_complete cause any practical, noticeable different to running my program?

(The reason I ask is I'm building an interface class which will accommodate decomposable "back-ends" some of which could be asynchronous. I'm hoping to use standard functions for the public (reusable) methods of the interface class so one API can be maintained for all code without messing up the use of asynchronous back-ends where an event-loop is available.)

Update: I didn't check the code properly and the first version was completely invalid, hence rewrite.

2
  • It actually depends. Foo will be executed synchronously while Bar not. It might happen that the scheduling/distribution might be important, i.e. it might make a difference for final user. Commented Dec 21, 2015 at 20:04
  • Yes, foo() is a blocking call. Also run_until_complete cannot be called with already running event loop Commented Dec 22, 2015 at 11:27

3 Answers 3

3

loop.run_until_complete() should be used outside of coroutine on very top level. Calling run_until_complete() with active (running) event loop is forbidden.

Also loop.run_until_complete(f) is a blocking call: execution thread is blocked until f coroutine or future becomes done.

async def is a proper way to write asynchronous code by making concurrent coroutines which may communicate with each other.

async def requires running event loop (either loop.run_until_complete() or loop.run_forever() should be called).

Sign up to request clarification or add additional context in comments.

2 Comments

Ok, so there's no reasonably way to build an interface which can be used for both synchronous and asynchronous code.
No. For now the best recommended way is to build async interface and make sync clone of them by adding stub functions running async counterparts with help of run_until_complete()
1

There is a world of difference. It is a SyntaxError to use await in a normal function def function.

import asyncio

async def atest():
    print("hello")

def test():
    await atest()

async def main():
    await atest()
    test()

--

File "test.py", line 9
    await atest()
              ^
SyntaxError: invalid syntax

3 Comments

Yes but as explained lets assume we're calling them thing (coroutine or function) from inside a coroutine.
No, it's a SyntaxError no mater what. You can easily try it for yourself.
yes you're right, my bad for not checking the code before submitted the question. I'll update the question.
-1

I do not believe so. I have used both and have not really seen a difference. I prefer foo just because I have used it more and understand it a bit better, but it is up to you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.