Как увеличить производительность цикла for в python

Другая неудачная практика может вызвать эту проблему, которая еще не указана.

См. этот фрагмент кода:


Все в порядке, верно?

Что делать, если «a_important_file.php»:



 ----------This is the end of the an_important_file-------------------

Это не сработает? Почему? Потому что уже создана новая строка.

Теперь, хотя это не общий сценарий, что, если вы используете структуру MVC, которая загружает большое количество файлов перед передачей данных на ваш контроллер? Это не необычный сценарий. Будьте готовы к этому.

Из PSR-2 2.2:


  • Все файлы PHP ДОЛЖНЫ использовать Unix LF (linefeed) line ending .
  • Все файлы PHP ДОЛЖНЫ заканчиваться на single blank line.
  • Тег закрытия?> ДОЛЖЕН быть omitted из файлов, содержащих only php

Поверьте, следующие стандарты могут сэкономить вам много часов из вашей жизни:)

1
задан hpaulj 16 January 2019 в 21:20
поделиться

2 ответа

Я предложил использовать numba в комментариях. Вот пример:

import numba
import numpy as np

def py_func(dt, F, P1):
    f = np.random.randn(1, int(60 / dt))
    ns = f.size
    yo = np.zeros((3))
    y1 = np.zeros((3, ns), order='F')
    for i in range(ns-1):
        y1[:, i] = np.dot(P1, f[:, i]) + np.reshape(np.dot(F, yo), (3))
        yo = y1[: , i]
    return yo

@numba.jit(nopython=True)
def numba_func(dt, F, P1):
    f = np.random.randn(1, int(60 / dt))
    ns = f.size
    yo = np.zeros((3))
    y1 = np.zeros((3, ns))
    for i in range(ns-1):
        y1[:, i] = np.dot(P1, f[:, i]) + np.reshape(np.dot(F, yo), (3))
        yo = y1[: , i]
    return yo

Вы не можете использовать порядок 'F' с numba, так как он использует массивы типа C, а не массивы FORTRAN.

Различия во времени показаны ниже:

Петля чистого питона:

%%timeit
py_func(dt, F, P1)

Результаты:

2.88 s ± 100 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Нумба:

%%timeit
numba_func(dt, F, P1)
[1113 ] Результаты:

588 ms ± 10.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
0
ответ дан PMende 16 January 2019 в 21:20
поделиться

Я немного оптимизировал ваш код, время выполнения для меня сократилось с 2,8 до примерно 1,2 с. Прежде чем искать более быстрых интерпретаторов, я рекомендую вам выполнить профилирование (см. Line_profiler) и попытаться удалить все, что вы можете, из внутреннего цикла. Лучше избегать любых явных циклов for и полагаться на такие простые функции, как dot, einsum и т. Д.

Думаю, еще есть место для оптимизации. Я не думаю, что я изменил ваши ценности, но лучше проверить. С другими инструментами, такими как numba или cython ( cython.org ) или pypy ( pypy.org ), я думаю, ваше время выполнения значительно улучшится.

#!/usr/bin/env python3

import numpy as np
import time

np.random.seed(0)

#@profile
def run():
    dt = 0.0001
    f = np.random.randn(1, int(60 / dt))
    ns = np.size(f)
    yo = np.zeros((3))
    F = np.array([[1, 0.0001, 0], [0.001, 1, 0.0001], [0.001, 0, 1]])
    P1 = np.transpose(np.array([[0, 0.0001, 0]]))
    start_time = time.time()
    y1 = np.outer(f, P1)
    for i in range(ns-1):
        y1[i] += F@yo
        yo = y1[i]
    print("--- %s seconds ---" % (time.time() - start_time))
    y1 = y1.T
    print(yo)

run()
0
ответ дан Jonas B. 16 January 2019 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: