Есть ли лучший способ сделать анализ времени выполнения, чем этот? - PullRequest
0 голосов
/ 04 апреля 2019

В настоящее время у меня есть 2 разные функции с опциями для их векторизации: acc_rej_sine(max_iter, algorithm=None) и analytical_sine(max_iter, algorithm=None), для которых я пытаюсь сравнить их время выполнения с вычисленным числом итераций. то есть сравнить все 4 метода; 2 петли, 2 векторизации. По сути, мой код выглядит примерно так:

def analytical_sine(max_iter, algorithm=None):
    if algorithm is None:
        count = 0
        analytical_hist = []
        for i in range(max_iter):
            count += 1
            progress = round((count/max_iter)*100)
            sys.stdout.write('\r' + str(progress) + '%')
            uni_dist = np.random.uniform(0, 1)
            arccos = np.arccos(1 - 2*uni_dist)
            analytical_hist.append(arccos)
    elif algorithm is "vectorise":
        analytical_hist = np.arccos(1 - 2*np.random.uniform(0, 1, max_iter))

    return analytical_hist

def acc_rej_sine(max_iter, algorithm=None):
    x = np.random.uniform(0, np.pi, max_iter)
    y = np.random.rand(max_iter)
    if algorithm is None:
        accepted_x = []
        j = count = 0
        for i in range(max_iter):
            count += 1
            progress = round((count/max_iter)*100)
            sys.stdout.write('\r' + str(progress) + '%')
            if y[i] <= np.sin(x[i]):
                accepted_x.append(x[i])
                j += 1
    elif algorithm is "vectorise":
        accepted_x = np.extract((y <= np.sin(x)), x)

    return accepted_x

def runtime(func, runs, max_iter, algorithm=None):
    time = []
    for i in range(runs):
        start = timer()
        func()
        end = timer()
        time.append((end-start))
    error = np.std(time)
    time = sum(time)/runs

    return time, error

def time_analysis():
    time1, time2, time3, time4 = [], [], [], []
    error1, error2, error3, error4 = [], [], [], []
    for i in np.arange(1, 8, 1):
        max_iter = 10**i
        time, error = runtime(analytical_sine, 5, int(max_iter))
        time1.append(time)
        error1.append(error)
        time, error = runtime(analytical_sine, 5, int(max_iter), "vectorise")
        time2.append(time)
        error2.append(error)
        time, error = runtime(acc_rej_sine, 5, int(max_iter))
        time3.append(time)
        error3.append(error)
        time, error = runtime(acc_rej_sine(max_iter), 5, int(max_iter), "vectorise")
        time4.append(time)
        error4.append(error)
    return [time1, time2, time3, time4], [error1, error2, error3, error4]

# to run the code I would probably do something like this
time, error = time_analysis()
#then if I wanna plot number of iterations vs run time with errors I would probably do something along the lines of
plt.plot(max_iter, time) # max_iter would be a list of [10**i for i in np.arange(1, 8, 1)]
plt.errorbar(error)

Таким образом, идея в том, что моя функция runtime() позволит мне вставить любую из 4 функций, которые я хочу сравнить (которые в настоящее время еще не работают, и я не могу / не выяснил почему) и запустите его 5 раз, определите среднее время выполнения и стандартное отклонение как ошибку. В свою очередь, моя time_analysis() функция будет запускаться runtime() для разных функций для разных max_iter (макс. Итераций), что выглядит как [10, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7], поэтому я могу построить максимальное количество итераций в зависимости от времени выполнения. Однако весь этот метод кажется довольно громоздким и не элегантным, так как мой time_analysis() требует от меня многократного отработки времени и ошибок и добавления его в список. Есть ли лучший способ рассчитать время? (Также мой runtime() пока не работает, лол, потому что мой аргумент algorithm, кажется, создает что-то не callable)

...