Anti-pattern: Processing results in submission order using ray.get increases runtime#

Avoid processing independent results in submission order using ray.get() because results may be ready in a different order than the submission order.

Suppose you submit a batch of tasks and need to process each result once it’s done. If each task takes a different amount of time to finish and you process results in submission order, you may waste time waiting for all the slower tasks that you submitted earlier to finish, even though later, faster tasks have already finished. These slower tasks are stragglers.

Instead, process the tasks in the order that they finish by using ray.wait() to speed up total time to completion.

../../_images/ray-get-submission-order.svg

Processing results in submission order versus completion order#

Code example#

import random
import time
import ray

ray.init()


@ray.remote
def f(i):
    time.sleep(random.random())
    return i


# Anti-pattern: process results in the submission order.
sum_in_submission_order = 0
refs = [f.remote(i) for i in range(100)]
for ref in refs:
    # Blocks until this ObjectRef is ready.
    result = ray.get(ref)
    # process result
    sum_in_submission_order = sum_in_submission_order + result

# Better approach: process results in the completion order.
sum_in_completion_order = 0
refs = [f.remote(i) for i in range(100)]
unfinished = refs
while unfinished:
    # Returns the first ObjectRef that is ready.
    finished, unfinished = ray.wait(unfinished, num_returns=1)
    result = ray.get(finished[0])
    # process result
    sum_in_completion_order = sum_in_completion_order + result

Other anti-patterns related to ray.get() are the following: