Библиотека time.time () возвращает неожиданный результат при использовании joblib - PullRequest
0 голосов
/ 09 октября 2018

У меня есть программа, которая создает несколько экземпляров класса, Test, а затем выполняет некоторую работу над каждым экземпляром класса, отслеживая, сколько времени заняла работа.Недавно я решил распараллелить этот код, используя библиотеку joblib, и столкнулся с ошибкой: переменная total_time в конце теперь равна 0.0.

Среда python на моей машине:

$ python3
Python 3.7.0 (default, Sep 18 2018, 18:47:08) 
[Clang 10.0.0 (clang-1000.10.43.1)] on darwin

Ниже приведен MCVE для этой проблемы:

import time
import random
import multiprocessing
import joblib

class Test:
    def __init__(self):
        self.name = ""
        self.duration = 0.0

def add_test(a):
    temp = Test()
    temp.name = str(a)
    return temp


def run_test(test):
    test_start = time.time()
    rand = random.randint(1,3)
    time.sleep(rand)
    test_end = time.time()
    test.duration = round(test_end - test_start, 3)
    print(f"Test {test.name} ran in {test.duration}")

def main():
    tests = []
    for a in range(1,10):
        tests.append(add_test(a))

    num_cores = multiprocessing.cpu_count()
    joblib.Parallel(n_jobs=num_cores)(joblib.delayed(run_test)(test) for test in tests)

    total_time = round(sum(test.duration for test in tests), 3)

    print(f"This run took {total_time} seconds.")

if __name__ == '__main__':
    main()

Если я добавлю print(list(test.duration for test in tests)) в main()Я вижу, что test.duration - это 0.0 после вызова run_test().видно из запуска указанного выше ввода, test.duration установлен в ненулевое значение (где это уместно) внутри run_test().

Я не слишком знаком с классами Python или библиотекой joblib, поэтому я не уверен, что проблема, с которой я сталкиваюсь, связана с неправильным использованием классов или с другой проблемой, которая мне не подходит.

Спасибо!

1 Ответ

0 голосов
/ 09 октября 2018

Благодаря num8lock на Reddit вот правильный способ решить эту проблему:

import time
import random
import multiprocessing
import joblib

class Test:
    def __init__(self, name):
        self.name = name
        self.duration = 0.0
        self.start = time.perf_counter()

    def run(self):
        rand = random.randint(1,3)
        time.sleep(rand)
        _end = time.perf_counter()
        self.duration = _end - self.start
        print(f"Test {self.name} ran in {self.duration}")
        return self.duration

def add(a):
    return Test(str(a))

def make_test(test):
    return test.run()

def main():
    num_cores = multiprocessing.cpu_count()
    tests = []
    for a in range(1,10):
        tests.append(add(a))

    jobs = joblib.Parallel(n_jobs=num_cores)(joblib.delayed(make_test)(t) for t in tests)
    total_time = sum(job for job in jobs)
    print(f"This run took {total_time} seconds.")

if __name__ == '__main__':
    main()
...